home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 001a / mskrmsrc.zip / MSSSHO.ASM < prev    next >
Assembly Source File  |  1991-10-24  |  80KB  |  2,738 lines

  1.     name    msssho
  2. ; File MSSSHO.ASM
  3.     include mssdef.h
  4. ;       Copyright (C) 1982,1991, Trustees of Columbia University in the
  5. ;       City of New York.  Permission is granted to any individual or
  6. ;       institution to use, copy, or redistribute this software as long as
  7. ;       it is not sold for profit and this copyright notice is retained.
  8. ; Show & Status commands
  9. ; edit history:
  10. ; 6 Sept 1991 version 3.11
  11. ; Last edit 6 Sept 1991
  12.  
  13.     public    shorx, shomac, shcom, shfile, shlog, shpro, shscpt, shserv
  14.     public    shterm, status, statc, stat0, srchkw, srchkb, shmem
  15.     public    partab, destab, seoftab, blktab, dmpname, lsesnam, lpktnam
  16.     public    ltranam, incstb, inactb, rxoffmsg, rxonmsg, lnout, lnouts
  17.     public    shosta, begtim, endtim, fsta, ssta    ; statistics procedures
  18.     public    rtmsg, rppos, stpos, rprpos, sppos, perpos, cxerr, frpos
  19.     public    fmtdsp, ermsg, msgmsg, init, cxmsg, intmsg, kbpr, perpr
  20.     public    winpr, windflag, pktsize, clrfln, oldkbt, oldper
  21.     public  wrpmsg, prttab, pasz, shovar, prnname
  22.  
  23. mcclen    equ    macmax*10
  24.                 ; equates for screen positioning
  25. scrser    equ    0209H        ; place for server state display line
  26. scrfln    equ    0316H        ; place for file name
  27. scrkb    equ    0416H        ; Place for percent transferred
  28. scrper    equ    0516H        ; Place for Kbytes transferred
  29. scrst    equ    0616H        ; Place for status
  30. scrnp    equ    0816H        ; Place for number of packets
  31. scrsz    equ    0916h        ; packet size
  32. scrnrt  equ    0A16H        ; Place for number of retries
  33. screrr  equ    0B16H        ; Place for error msgs
  34. scrmsg    equ    0C16H        ; Last message position
  35. scrsp    equ    0E00H        ; Place for send packet
  36. scrrp    equ    1300H        ; Place for receive packet
  37. scrrpr    equ    1700H        ; Prompt when Kermit ends (does cr/lf)
  38. braceop    equ    7bh            ; opening curly brace
  39. bracecl    equ    7dh            ; closing curly brace
  40.  
  41. data    segment
  42.     extrn    termtb:byte, comptab:byte, portval:word,dtrans:byte,rdbuf:byte
  43.     extrn    trans:byte, curdsk:byte, flags:byte, maxtry:byte, comand:byte
  44.     extrn    spause:byte, taklev:byte, takadr:word, alrhms:byte, bdtab:byte
  45.     extrn    denyflg:word, rxtable:byte, mcctab:byte, script:byte
  46.     extrn    errlev:byte, luser:byte, srvtmo:byte, mccptr:word, thsep:byte
  47.     extrn    scpbuflen:word, setchtab:byte, xfchtab:byte, xftyptab:byte
  48.     extrn    tfilsz:word, diskio:byte, tloghnd:word, dosnum:word
  49.     extrn    templp:byte, windused:byte, numpkt:word, verident:byte
  50.     extrn    decbuf:byte, flotab:byte, warntab:byte, valtab:byte
  51.     extrn    valbuf:byte
  52.  
  53. crlf    db       cr,lf,'$'
  54. eqs    db    ' = $'
  55. spaces    db    '    $'
  56.  
  57. outlin1 db    6 dup (' '),'$'
  58. ;;;    version appears here
  59. outlin2 db    cr,lf,lf
  60.         db      cr,lf,'           File name:'
  61.         db      cr,lf,'  KBytes transferred:'
  62.         db      cr,lf
  63.         db      cr,lf
  64.         db      cr,lf
  65.         db      cr,lf,'   Number of packets:'
  66.     db    cr,lf,'       Packet length:'
  67.         db      cr,lf,'   Number of retries: 0'
  68.         db      cr,lf,'          Last error:'
  69.         db      cr,lf,'        Last message:'
  70.         db      cr,lf,'$'
  71.  
  72.  
  73. permsg    db    cr,' Percent transferred:$'
  74. cxzhlp    db    'X: cancel file, Z: cancel group, E: exit nicely,'
  75.     db    ' C: exit abruptly, Enter: retry$'
  76. erword    db    cr,lf,'Error: $'
  77. msword    db    cr,lf,'Message: $'
  78. rtword    db    cr,lf,'Retry $'
  79. cxzser    db    cr,lf,' Type X to cancel file, Z to cancel group,'
  80.     db    cr,lf,' E to exit nicely, C to quit abruptly,'
  81.     db    cr,lf,' or Enter to retry',cr,lf,'$'
  82. windmsg    db    ' Window slots in use:$'
  83. windmsg2 db    ' of $'
  84. windflag db    0        ; flag to init windows msg, 0=none
  85. oldwind    db    -1        ; last windows in use value
  86. oldper    dw    0        ; old percentage
  87. oldkbt    dw    0        ; old KB transferred
  88. wrpmsg    db    0        ; non-zero if we wrote percent message
  89. fmtdsp    db    0        ; non-zero if formatted display in use
  90. prepksz    dw    0        ; previous packet size
  91. onehun    dw    100
  92. denom    dw    0
  93. temp    dw    0
  94. temp1    dw    0
  95. shmcnt    dw    0
  96. sixteen    dw    16
  97. infms1    db    'Server mode: type Control-C to exit',cr,lf,'$'
  98. infms7    db    'File interrupt',cr,lf,'$'
  99. infms8    db    'File group interrupt',cr,lf,'$'
  100. infms9    db    'User ',5eh,'  interrupt',cr,lf,'$'
  101.  
  102. partab    db    5
  103.     mkeyw    'none (8-bit data) ',PARNON
  104.     mkeyw    'even (7-bit data) ',PAREVN
  105.     mkeyw    'odd (7-bit data) ',PARODD
  106.     mkeyw    'mark (7-bit data) ',PARMRK
  107.     mkeyw    'space (7-bit data) ',PARSPC
  108.  
  109. destab    db    3
  110.     mkeyw    'Disk',1
  111.     mkeyw    'Printer',0
  112.     mkeyw    'Screen',2
  113.  
  114. seoftab    db    2
  115.     mkeyw    'Ctrl-Z',1
  116.     mkeyw    'NoCtrl-Z',0
  117.  
  118. ; What type of block check to use
  119. blktab    db    3
  120.     mkeyw    '1-char-checksum',1
  121.     mkeyw    '2-char-checksum',2
  122.     mkeyw    '3-char-CRC-CCITT',3
  123.  
  124. modtab    db    3                ; Mode line status
  125.     mkeyw    'off',0
  126.     mkeyw    'on',1
  127.     mkeyw    'on (owned by host)',2
  128.  
  129. ontab    db    2
  130.     mkeyw    'off',0
  131.     mkeyw    'on',1
  132.  
  133. unkctab db    2            ; unknown character-set disposition
  134.     mkeyw    'keep',0
  135.     mkeyw    'cancel',1
  136.  
  137. logsta    db    8            ; Log Status table
  138.     mkeyw    'off',logoff        ; suspended or no logging
  139.     mkeyw    'Packet',logpkt
  140.     mkeyw    'Session',logses
  141.     mkeyw    'Packet+Session',logpkt+logses
  142.     mkeyw    'Transaction',logtrn
  143.     mkeyw    'Packet+Transaction',logpkt+logtrn
  144.     mkeyw    'Session+Transaction',logses+logtrn
  145.     mkeyw    'Packet+Session+Transaction',logpkt+logses+logtrn
  146.  
  147. dissta    db    6            ; Status of Display mode
  148.     mkeyw    'Quiet, 7-bit',dquiet
  149.     mkeyw    'Regular, 7-bit',dregular
  150.     mkeyw    'Serial, 7-bit',dserial
  151.     mkeyw    'Quiet, 8-bit',dquiet+d8bit
  152.     mkeyw    'Regular, 8-bit',dregular+d8bit
  153.     mkeyw    'Serial, 8-bit',dserial+d8bit
  154.  
  155. endistab db    2            ; Server ENABLE/DISABLE status
  156.     mkeyw    'enabled',0
  157.     mkeyw    'disabled',1
  158.  
  159. inactb    db    2                ; Set Input Timeout Action
  160.     mkeyw    'Proceed',0            ;[jrs]
  161.     mkeyw    'Quit',1            ;[jrs]
  162.  
  163. incstb    db    2                ;[jrs] Set Input Case
  164.     mkeyw    'Ignore',0dfh            ;[jrs]
  165.     mkeyw    'Observe',0ffh            ;[jrs]
  166.  
  167.                 ; Statistics data storage area
  168. fsta    statinfo <>        ; for last operation values
  169. ssta    statinfo <>        ; for session values
  170. sflag    dw    0        ; flag for send (1) or receive (0)
  171.                 ;   80h = begtim started
  172.  
  173. statmsg    db   cr,lf,lf,'                               Last Transfer         '
  174.     db    ' Entire Session'
  175.     db    cr,lf,'   Item                      Sent       Rec''d       '
  176.     db    ' Sent       Rec''d',cr,lf,'$'
  177. fchmsg    db    cr,lf,' File characters:    $'
  178. spmsg    db    cr,lf,' Comms port chars:   $'
  179. pktmsg    db    cr,lf,' Packets:            $'
  180. nakmsg    db    cr,lf,' NAKs:               $'
  181. retmsg    db    cr,lf,' Packet retries:     $'
  182. timemsg    db   cr,lf,lf,' Protocol time, secs:$'
  183. chpsmsg    db    cr,lf,' File characters/sec:$'
  184. spedmsg    db    cr,lf,' Comms port bits/sec:$'
  185. sndmsg    db    'Sent ',0
  186. rcvmsg    db    'Recv ',0
  187. date    db    '00:00:00 00 Jan 1980',0
  188. datelen    equ    $-date-1
  189. atmsg    db    cr,lf,'  at '
  190. atlen    equ    $-atmsg
  191. fasmsg    db    ' as '
  192. faslen    equ    $-fasmsg
  193. fsucmsg    db    ', completed, bytes: ',0
  194. fbadmsg    db    ', failed, bytes: ',0
  195. fintmsg    db    ', interrupted, bytes: ',0
  196. months    db    'JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP'
  197.     db    'OCT','NOV','DEC'
  198.     even
  199. tens    dd    1,10,100,1000,10000,100000,1000000,10000000,100000000
  200.     dd    1000000000
  201. tenslen    equ    ($-tens) / 4    ; number of double words in array tens
  202. lnoutsep db    0        ; non-zero to separate thousands in lnout
  203.                 ; end statistics data area
  204. sixty    dw    60
  205. ten    dw    10
  206.  
  207. logmsg    db    'Kind         Default filename          Status$'
  208. nologmsg db    '(not active)$'
  209. lsesmsg    db    'Session       (Session.log)$'
  210. lpktmsg    db    'Packets       (Packet.log)$'
  211. ltramsg    db    'Transactions  (Transact.log)$'
  212. dmpmsg    db    'Screen Dump, in Connect mode$'
  213. dmpmsg2    db    'Dump screen: $'    ; for general STATUS display
  214. prnmsg    db    'Printer name, in Connect mode: $'
  215. modst    db    'Mode line: $'
  216. locst    db    'Local echo: $'
  217. duphlf    db    'Duplex: half$'
  218. dupful    db    'Duplex: full$'
  219. belon    db    'Ring bell after transfer$'
  220. beloff    db    'No bell after transfer$'
  221. vtemst    db    'Terminal emulation: $'        ; terminal emulator
  222. portst    db    'Communications port: $'
  223. capmsg    db    'Logging: $'
  224. eofmsg    db    'EOF mode: $'
  225. flost    db    'No flow control used$'
  226. floxmsg    db    'Flow control: xon/xoff $'
  227. flost1    db    'Flow control: $'
  228. handst    db    'Handshake used: $'
  229. destst    db    'Destination: $'
  230. xtypmsg    db    'File Type: $'
  231. xchmsg    db    'Transfer char-set: $'
  232. chmsg    db    'File char set: $'
  233. unkmsg    db    'Unknown-char-set: $'
  234. diskst    db    'Dir: $'
  235. blokst    db    'Block check used: $'
  236. sqcst    db    'Send control char prefix: $'
  237. rqcst    db    'Receive control char prefix: $'
  238. debon    db    'Debug: $'
  239. flwon    db    'Collision (file name): $'
  240. parmsg    db    'Parity: $'
  241. abfdst    db    'Incomplete file: discard$'
  242. abfkst    db    'Incomplete file: keep$'
  243. sndmsg1    db    'Send Delay: $'
  244. sndmsg2    db    ' sec, Pause: $'
  245. sndmsg3    db    ' ms$'
  246. msohst    db    'Start-of-Packet char S: ',5eh,'$'
  247. meolst    db    'End-of-Packet char   S: ',5eh,'$'
  248. msrec    db    '  R: ',5eh,'$'
  249. msrecv    db    '  R: $'
  250. tmost    db    'Timeout (seconds)    S: $'
  251. stimst    db    'Send timeout (seconds): $'
  252. rtimst    db    'Receive timeout (seconds): $'
  253. spakst    db    'Send packet size (maximum): $'
  254. rpakst    db    'Receive packet size (maximum): $'
  255. spakst1    db    'Send packet size (current): $'
  256. rpakst1    db    'Receive packet size (current): $'
  257. snpdst    db    'Number of padding chars S: $'
  258. spadst    db    'Padding char S: ',5eh,'$'
  259. retrymsg db    'Retry send/receive packet limit: $'
  260. swinst    db    'Sliding window slots (max): $'
  261. dispst    db    'Display: $'
  262. timmsg    db    'Timer: $'
  263. srvmsg    db    'Timeout (sec) waiting for a transaction: $'
  264. dblmsg    db    'Send double-char: $'
  265. ignmsg    db    'Receive ignore-char: $'
  266. escmes    db    'Escape character: $'
  267. scpmsg    db    'Script commands Echo, If, Input, Output, Pause, Reinput,'
  268.     db    ' Transmit, Wait$'
  269. sechmsg    db    'Input echoing: $'
  270. scasmsg    db    'Case sensitivity: $'
  271. stmo1msg db    'Timeout (seconds): $'
  272. stmo2msg db    'Timeout-action: $'
  273. sxfilmsg db    'Transmit fill-empty-line: $'
  274. sxlfmsg db    'Transmit line-feeds-sent: $'
  275. sxpmtmsg db    'Transmit prompt character: $'
  276. stbufmsg db    'INPUT-buffer-length: $'
  277. stinbmsg db    'INPUT-BUFFER follows: $'
  278. takon    db    'Take-echo: $'
  279. atton    db    'Attributes packets: $'
  280. sachmsg    db    '  Character-set: $'
  281. sadtmsg    db    '  Date-Time: $'
  282. salnmsg    db    '  Length: $'
  283. satymsg    db    '  Type: $'
  284. baudrt    db    'Speed: $'
  285. unrec    db    'unknown$'
  286. kbdmsg    db    'Keyboard translation: $'
  287. stcntmsg db    'Take/Macro COUNT: $'
  288. stargmsg db    'Take/Macro ARGC: $'
  289. nonemsg    db    'not active$'
  290. sterlmsg db    'Errorlevel: $'
  291. stalrmsg db    'Alarm time: $'
  292. lusrmsg    db    'Login Username: $'
  293. servmsg    db    'Server commands available to remote user: $'
  294. scwdmsg    db    'CD/CWD: $'
  295. sdelmsg    db    'DELETE: $'
  296. sdirmsg    db    'DIR:    $'
  297. sfinmsg    db    'FINISH: $'
  298. sgetmsg    db    'GET:    $'
  299. shstmsg    db    'HOST:   $'
  300. skermsg    db    'KERMIT: $'
  301. slogmsg    db    'LOGIN:  $'
  302. ssndmsg    db    'MESSAGE:$'
  303. sprtmsg    db    'PRINT:  $'
  304. sspcmsg    db    'SPACE:  $'
  305. stypmsg    db    'TYPE:   $'
  306. stekmsg    db    'Tek4010: $'
  307. nonmsg    db    'none$'
  308. onmsg    db    'on'
  309. offmsg    db    'off'
  310. moremsg    db    cr,lf,'-- More -- press space for more,'
  311.     db    ' q or Control-C to quit. $'
  312. rxoffmsg db    cr,lf,'  Input Translation is off$'
  313. rxonmsg    db    cr,lf,'  Input Translation is on$'
  314.  
  315. shormsg    db    cr,lf,'  Translation table of received byte codes while'
  316.     db    ' in CONNECT mode -'
  317.     db    cr,lf,'  Format: [received byte (decimal) -> local byte'
  318.     db    ' (decimal)]',cr,lf,'$'
  319. shopm1    db    ' [\$'            ; Show Translation material
  320. shopm2    db    ' -> \$'
  321. shopm3    db    '] $'
  322. shmmsg    db    ' name of macro, or press ENTER to see all$'
  323. shvmsg    db    ' name of \v(name) variable, or press ENTER to see all$'
  324. shom9m1    db    cr,lf,' Free space (bytes) for names: $'
  325. shom9m3    db    cr,lf,' No macro(s)$'
  326. shom9m4    db    '<cr>$'
  327. memmsg1    db    cr,lf,' DOS free memory (bytes):$'
  328. memmsg2    db    cr,lf,' Total free bytes: $'
  329. varstng    db    cr,lf,' \v($'
  330.  
  331. prterr    db    '?Unrecognized value$'
  332. lpktnam    db    'Packet.log',54 dup (0)    ; default packet log filename
  333. lsesnam    db    'Session.log',54 dup (0); default capture/session filename
  334. ltranam    db    'Transact.log',52 dup (0); default transaction log filename
  335. dmpname    db    'Kermit.scn',54 dup (0)    ; file name for screen dumps
  336. prnname    db    'PRN',61 dup (0)    ; file name for printer
  337.  
  338.     even
  339. stent    struc            ; structure for status information table sttab
  340. sttyp    dw    ?        ; type (actually routine to call)
  341. msg    dw    ?        ; message to print
  342. val2    dw    ?        ; needed value: another message, or tbl addr
  343. tstcel    dw    ?        ; address of cell to test, in data segment
  344. basval    dw    0        ; base value, if non-zero
  345. stent    ends
  346.  
  347. sttab    stent    <baudprt>                ; STATUS
  348.     stent    <srchkw,vtemst,termtb,flags.vtflg>    ; terminal emulator
  349.     stent    <srchkw,portst,comptab,flags.comflg>
  350.     stent    <srchkw,modst,modtab,flags.modflg>
  351.     stent    <srchkw,parmsg,partab,parflg,portval>
  352.     stent    <stlnum,spakst,,dtrans.slong>
  353.     stent    <onoff,locst,,ecoflg,portval>
  354.     stent    <stlnum,rpakst,,dtrans.rlong>
  355.     stent    <srchkw,flost1,flotab,floflg,portval>
  356.     stent    <prsar,msohst,msrec,trans.ssoh,trans.rsoh>
  357.     stent    <prhnd>
  358.     stent    <prsar,meolst,msrec,trans.seol,trans.reol>
  359.     stent    <msg2,dupful,duphlf,duplex,portval>
  360.     stent    <prsarv,tmost,msrecv,dtrans.stime,trans.rtime>
  361.     stent    <drnum,diskst,,curdsk>
  362.     stent    <prsnd, sndmsg1>
  363.     stent    <srchkw,flwon,warntab,flags.flwflg>
  364.     stent    <stnum,retrymsg,,maxtry>
  365.     stent    <srchkw,destst,destab,flags.destflg>
  366.     stent    <srchkw,blokst,blktab,dtrans.chklen>
  367.     stent    <msg2,abfkst,abfdst,flags.abfflg>
  368.     stent    <srchkw,capmsg,logsta,flags.capflg>
  369.     stent    <srchkw,eofmsg,seoftab,flags.eofcz>
  370.     stent    <srchkw,debon,logsta,flags.debug>
  371.     stent    <srchkw,dispst,dissta,flags.remflg>
  372.     stent    <onoff,timmsg,,flags.timflg>
  373.     stent    <onechr,escmes,,trans.escchr>
  374.     stent    <srchkw,kbdmsg,ontab,flags.xltkbd>
  375.     stent    <vtstat>
  376.     dw    0                ; end of table
  377.  
  378. stcom    stent    <srchkw,portst,comptab,flags.comflg>    ; SHOW COMMS
  379.     stent    <baudprt>
  380.     stent    <onoff,locst,,ecoflg,portval>
  381.     stent    <srchkw,parmsg,partab,parflg,portval>
  382.     stent    <prhnd>
  383.     stent    <srchkw,flost1,flotab,floflg,portval>
  384.     stent    <msg2,dupful,duphlf,duplex,portval>
  385.     stent    <srchkw,dispst,dissta,flags.remflg>
  386.     stent    <srchkw,debon,logsta,flags.debug>
  387.     dw    0
  388.  
  389. stfile    stent    <drnum,diskst,,curdsk>            ; SHOW FILE
  390.     stent    <msg2,abfkst,abfdst,flags.abfflg>
  391.     stent    <srchkw,destst,destab,flags.destflg>
  392.     stent    <srchkw,flwon,warntab,flags.flwflg>
  393.     stent    <srchkw,eofmsg,seoftab,flags.eofcz>
  394.     stent    <srchkww,chmsg,setchtab,flags.chrset>
  395.     stent    <srchkw,xtypmsg,xftyptab,dtrans.xtype>
  396.     stent    <srchkw,xchmsg,xfchtab,dtrans.xchset>
  397.     stent    <msg2,beloff,belon,flags.belflg>
  398.     stent    <srchkw,unkmsg,unkctab,flags.unkchs>
  399.     stent    <stmsg,atton>
  400.     stent    <stmsg,spaces>
  401.     stent    <srchkb,sachmsg,ontab,attchr,flags.attflg>
  402.     stent    <stmsg,spaces>
  403.     stent    <srchkb,sadtmsg,ontab,attdate,flags.attflg>
  404.     stent    <stmsg,spaces>
  405.     stent    <srchkb,salnmsg,ontab,attlen,flags.attflg>
  406.     stent    <stmsg,spaces>
  407.     stent    <srchkb,satymsg,ontab,atttype,flags.attflg>
  408.     dw    0
  409.  
  410. stlog    stent    <stmsg,logmsg>                ; SHOW LOG
  411.     stent    <stmsg,lpktmsg>
  412.     stent    <msg2b,nologmsg,lpktnam,logpkt,flags.capflg>
  413.     stent    <stmsg,lsesmsg>
  414.     stent    <msg2b,nologmsg,lsesnam,logses,flags.capflg>
  415.     stent    <stmsg,ltramsg>
  416.     stent    <msg2b,nologmsg,ltranam,logtrn,flags.capflg>
  417.     stent    <stmsg,dmpmsg>
  418.     stent    <stmsg,dmpname>
  419.     stent    <stmsg,prnmsg>
  420.     stent    <stmsg,prnname>
  421.     dw    0
  422.  
  423. stpro    stent    <stlnum,spakst,,dtrans.slong>        ; SHOW PROTOCOL
  424.     stent    <stlnum,rpakst,,dtrans.rlong>
  425.     stent    <stlnum,spakst1,,trans.slong>
  426.     stent    <stlnum,rpakst1,,trans.rlong>
  427.     stent    <stnum,stimst,,dtrans.stime>
  428.     stent    <stnum,rtimst,,trans.rtime>
  429.     stent    <onechr,sqcst,,dtrans.squote>
  430.     stent    <onechr,rqcst,,trans.rquote>
  431.     stent    <prsar,msohst,msrec,trans.ssoh,trans.rsoh>
  432.     stent    <prsarv,snpdst,msrecv,dtrans.spad,trans.rpad>
  433.     stent    <prsar,meolst,msrec,trans.seol,trans.reol>
  434.     stent    <prsar,spadst,msrec,dtrans.spadch,trans.rpadch>
  435.     stent    <onechr,dblmsg,,dtrans.sdbl>
  436.     stent    <onechr,ignmsg,,dtrans.rign>
  437.     stent    <prsnd,sndmsg1>
  438.     stent    <srchkw,blokst,blktab,dtrans.chklen>
  439.     stent    <stnum,retrymsg,,maxtry>
  440.     stent    <stnum,swinst,,dtrans.windo>
  441.     stent    <onoff,timmsg,,flags.timflg>
  442.     stent    <prhnd>
  443.     stent    <srchkw,debon,logsta,flags.debug>
  444.     stent    <srchkw,capmsg,logsta,flags.capflg>
  445.     stent    <srchkw,xtypmsg,xftyptab,dtrans.xtype>
  446.     stent    <srchkww,chmsg,setchtab,flags.chrset>
  447.     stent    <stmsg,atton>
  448.     stent    <srchkw,xchmsg,xfchtab,dtrans.xchset>
  449.     stent    <srchkb,sachmsg,ontab,attchr,flags.attflg>
  450.     stent    <stmsg,spaces>
  451.     stent    <srchkb,sadtmsg,ontab,attdate,flags.attflg>
  452.     stent    <stmsg,spaces>
  453.     stent    <srchkb,salnmsg,ontab,attlen,flags.attflg>
  454.     stent    <stmsg,spaces>
  455.     stent    <srchkb,satymsg,ontab,atttype,flags.attflg>
  456.     dw    0
  457.  
  458. stscpt    stent    <stmsg,scpmsg>                ; SHOW SCRIPT
  459.     stent    <onoff,sechmsg,,script.inecho>
  460.     stent    <srchkw,scasmsg,incstb,script.incasv>
  461.     stent    <stlnum,stmo1msg,,script.indfto>
  462.     stent    <srchkw,stmo2msg,inactb,script.inactv>
  463.     stent    <stalr,stalrmsg>
  464.     stent    <stlnum,stbufmsg,,scpbuflen>
  465.     stent    <stnum,sterlmsg,,errlev>
  466.     stent    <prfil>
  467.     stent    <onoff,sxlfmsg,,script.xmitlf>
  468.     stent    <onechr,sxpmtmsg,,script.xmitpmt>
  469.     stent    <stcnt,stcntmsg>
  470.     stent    <srchkw,takon,ontab,flags.takflg>
  471.     stent    <starg,stargmsg>
  472.     stent    <stmsg,stinbmsg>
  473.     stent    <stinbuf>
  474.     dw    0
  475.  
  476. stserv    stent    <pasz,lusrmsg,offset luser>        ; SHOW SERVER
  477.     stent    <stmsg,servmsg>
  478.     stent    <srchkb,scwdmsg,endistab,cwdflg,denyflg>
  479.     stent    <srchkb,skermsg,endistab,kerflg,denyflg>
  480.     stent    <srchkb,sdelmsg,endistab,delflg,denyflg>
  481.     stent    <srchkb,slogmsg,endistab,pasflg,denyflg>
  482.     stent    <srchkb,sdirmsg,endistab,dirflg,denyflg>
  483.     stent    <srchkb,ssndmsg,endistab,sndflg,denyflg>
  484.     stent    <srchkb,sfinmsg,endistab,finflg,denyflg>
  485.     stent    <srchkb,sprtmsg,endistab,prtflg,denyflg>
  486.     stent    <srchkb,sgetmsg,endistab,getsflg,denyflg>
  487.     stent    <srchkb,sspcmsg,endistab,spcflg,denyflg>
  488.     stent    <srchkb,shstmsg,endistab,hostflg,denyflg>
  489.     stent    <srchkb,stypmsg,endistab,typflg,denyflg>
  490.     dw    0
  491. stserv2    stent    <stnum,srvmsg,,srvtmo>
  492.     dw    0
  493.  
  494. stterm    stent    <srchkw,vtemst,termtb,flags.vtflg>    ; SHOW TERMINAL
  495.     stent    <srchkw,dispst,dissta,flags.remflg>
  496.     stent    <srchkb,stekmsg,endistab,tekxflg,denyflg>
  497.     stent    <onechr,escmes,,trans.escchr>
  498.     stent    <srchkw,modst,modtab,flags.modflg>
  499.     stent    <srchkw,kbdmsg,ontab,flags.xltkbd>
  500.     stent    <vtstat>
  501.     dw    0
  502.  
  503. shorxk    stent    <srchkw,kbdmsg,ontab,flags.xltkbd>
  504.     stent    <stmsg,spaces>
  505.     dw    0
  506.  
  507. data    ends
  508.  
  509. code    segment
  510.     extrn    comnd:near, decout:near, locate:near, prtscr:near, strlen:near
  511.     extrn    getbaud:near, vtstat:near, shomodem:near, nvaltoa:near
  512.     extrn    cmblnk:near, prtasz:near, putmod:near, clrmod:near
  513.     extrn    poscur:near, clearl:near, nout:near, dodec:near, buflog:near
  514.     extrn    dec2di:near
  515.  
  516.     assume    cs:code, ds:data, es:nothing
  517.  
  518. fstrlen    proc    far        ; FAR callable versions of items in seg code
  519.     call    strlen        ;  for calling from code segment code1 below
  520.     ret
  521. fstrlen    endp
  522. fdec2di    proc    far
  523.     call    dec2di
  524.     ret
  525. fdec2di    endp
  526. fprtscr    proc    far
  527.     call    prtscr
  528.     ret
  529. fprtscr    endp
  530. fprtasz    proc    far
  531.     call    prtasz
  532.     ret
  533. fprtasz    endp
  534. flnout    proc    far
  535.     call    lnout
  536.     ret
  537. flnout    endp
  538. flnouts    proc    far
  539.     call    lnouts
  540.     ret
  541. flnouts    endp
  542. fnvaltoa proc    far
  543.     call    nvaltoa
  544.     ret
  545. fnvaltoa endp
  546. ; Display asciiz message pointed to by DS:DX on Last error line
  547. ERMSG    PROC    NEAR
  548.     test    flags.remflg,dquiet    ; quiet screen?
  549.     jnz    ermsgx            ; nz = yes
  550.     push    si            ; position cursor to Last Error line
  551.     push    dx            ; save preexisting message pointer
  552.     test    flags.remflg,dserial    ; serial mode display?
  553.     jnz    erpo1            ; nz = yes
  554.     cmp    fmtdsp,0        ; formatted display?
  555.     jne    erpo2            ; ne = yes
  556. erpo1:    mov    ah,prstr
  557.     mov    dx,offset erword    ; put out word Error:
  558.     int    dos
  559.     jmp    short erpo3
  560. erpo2:    mov    dx,screrr
  561.     call    poscur
  562.     call    clearl            ; clear the line
  563. erpo3:    pop    dx            ; restore old pointer
  564.     mov    si,dx            ; string pointer
  565.     mov    cx,10            ; try ten items
  566.     cld
  567. ermsg1:    lodsb
  568.     cmp    al,' '            ; strip these leading spaces
  569.     loope    ermsg1
  570.     dec    si            ; backup to non-space
  571.     push    dx            ; preserve caller's dx
  572.     mov    dx,si
  573.     call    prtasz            ; display asciiz message
  574.     pop    dx
  575.     pop    si
  576. ermsgx:    ret
  577. ERMSG    ENDP
  578.  
  579. ; Decode and display Message packet pointed to by SI.
  580. MSGMSG    PROC    NEAR
  581.     test    flags.remflg,dquiet    ; quiet screen?
  582.     jnz    msgmsgx            ; nz = yes
  583.     cmp    [si].datlen,0        ; anything present?
  584.     je    msgmsgx            ; e = no
  585.     test    flags.remflg,dserial    ; serial mode display?
  586.     jnz    msgms1            ; nz = yes
  587.     cmp    fmtdsp,0        ; formatted display?
  588.     jne    msgms2            ; ne = yes
  589.     cmp    flags.xflg,0        ; packet header seen?
  590.     je    msgms2            ; e = no
  591. msgms1:    mov    ah,prstr
  592.     mov    dx,offset msword    ; put out word Message:
  593.     int    dos
  594.     jmp    short msgms3        ; display the message
  595. msgms2:    push    si
  596.     mov    dx,scrmsg        ; Last message line
  597.     call    poscur
  598.     call    clearl            ; clear the line
  599.     pop    si
  600. msgms3:    call    dodec            ; decode to decbuf, SI is pktinfo ptr
  601.     mov    dx,offset decbuf    ; final error message string, asciiz
  602.     call    prtasz            ; display asciiz message
  603. msgmsgx:ret
  604. MSGMSG    ENDP
  605.  
  606. ; Show number of retries message
  607.  
  608. RTMSG    PROC     NEAR
  609.     test    flags.remflg,dquiet    ; quiet display mode?
  610.     jnz    rtmsx            ; nz = yes
  611.     test    flags.remflg,dserver    ; in server mode?
  612.     jnz    rtms0            ; nz = yes
  613.     cmp    flags.xflg,0        ; receiving to screen?
  614.     jne    rtmsx            ; ne = yes
  615.     cmp    fmtdsp,0        ; formatted display?
  616.     je    rtms1            ; e = no, do as normal
  617. rtms0:    test    flags.remflg,dserial    ; serial mode display?
  618.     jnz    rtms1            ; nz = yes
  619.     push    ax
  620.     push    dx
  621.     push    si
  622.     mov    dx,scrnrt
  623.     call    poscur
  624.     call    clearl
  625.     pop    si
  626.     jmp    short rtms3
  627. rtms1:    push    ax
  628.     push    dx
  629.     mov    dx,offset rtword    ; display word Retry
  630.     mov    ah,prstr
  631.     int    dos
  632. rtms3:    mov    ax,fsta.pretry        ; number of retries
  633.     call    decout            ; write the number of group retries
  634.     pop    dx
  635.     pop    ax
  636. rtmsx:    ret
  637. RTMSG    ENDP
  638.  
  639. ; Reassure user that we acknowledge his ^X/^Z
  640.  
  641. INTMSG    PROC    NEAR
  642.     cmp    flags.cxzflg,0        ; anything there?
  643.     je    int1            ; e = no
  644.     test    flags.remflg,dserver    ; server mode?
  645.     jnz    int4            ; nz = yes
  646.     cmp    flags.xflg,0        ; writing to screen?
  647.     jne    int1            ; ne = yes, nothing to do
  648. int4:    test    flags.remflg,dquiet    ; quiet screen?
  649.     jnz    int1            ; yes, suppress msg
  650.     test    flags.remflg,dserial    ; serial mode display?
  651.     jz    int2            ; z = no
  652.     cmp    fmtdsp,0        ; formatted screen?
  653.     jne    int2            ; ne = yes
  654.     mov    dx,offset crlf        ; output initial cr/lf
  655.     mov    ah,prstr
  656.     int    dos
  657.     jmp    short int3        ; display the message
  658. int2:    mov    dx,scrmsg        ; last message position
  659.     call    poscur
  660.     call    clearl
  661. int3:    mov    dx,offset infms7    ; File interrupted
  662.     cmp    flags.cxzflg,'X'    ; File interrupt? 
  663.     je    int0            ; e = yes
  664.     mov    dx,offset infms8    ; File group interrupted
  665.     cmp    flags.cxzflg,'Z'    ; correct?
  666.     je    int0            ; e = yes
  667.     mov    dl,flags.cxzflg        ; say Control ^letter interrupt
  668.     mov    infms9+6,dl        ; store interrupt code letter
  669.     mov    dx,offset infms9
  670. int0:   mov    ah,prstr
  671.         int    dos
  672. int1:    ret
  673. INTMSG    ENDP
  674.  
  675. ;  Clear Last error and Last message lines
  676. cxerr:    mov    temp,0            ; say last error line
  677.     jmp    short cxcomm        ; do common code
  678.  
  679. CXMSG    PROC    NEAR
  680.     mov    temp,1            ; say last message line
  681.  
  682. cxcomm:    test    flags.remflg,dserver    ; server mode?
  683.     jnz    cxm1            ; nz = yes
  684.     cmp    flags.xflg,0        ; Writing to screen?
  685.     jne    cxm0            ; ne = yes
  686. cxm1:    cmp    fmtdsp,0        ; formatted display?
  687.     je    cxm0            ; e = no
  688.     push    dx
  689.     push     si
  690.     mov    dx,screrr        ; Last Error postion
  691.     cmp    temp,0            ; do last error line?
  692.     je    cxm2            ; e = yes
  693.     mov    dx,scrmsg        ; Last Message position
  694. cxm2:    call    poscur
  695.     call    clearl
  696.     pop    si
  697.     pop    dx
  698. cxm0:    ret
  699. CXMSG    ENDP
  700.  
  701. ;  Clear out the old filename on the screen. 
  702.  
  703. CLRFLN    PROC    NEAR
  704.     test    flags.remflg,dquiet     ; quiet display?
  705.     jnz    clrflnx            ; nz = yes
  706.     test    flags.remflg,dserial    ; serial display mode?
  707.     jnz    clrfln1            ; nz = yes, use just cr/lf
  708.     cmp    fmtdsp,0        ; formatted display?
  709.     je    clrfln1            ; e = no
  710.     mov    dx,scrfln
  711.     call    poscur
  712.     call    clearl            ; clear to end of line
  713.     ret
  714. clrfln1:push    ax            ; for serial display, does cr/lf
  715.     mov    ah,prstr
  716.     mov    dx,offset crlf
  717.     int    dos
  718.     pop    ax
  719. clrflnx:ret
  720. CLRFLN    ENDP
  721.  
  722.             ; display packet quantity and size, SI has pkt ptr
  723. PKTSIZE    PROC    NEAR
  724.     push    ax
  725.     push    dx
  726.     push    si
  727.     cmp    fmtdsp,0        ; formatted display?
  728.     je    pktsiz2            ; e = no, no display
  729.     mov    ax,[si].datlen        ; packet size (data part)
  730.     add    al,trans.chklen        ; plus checksum
  731.     adc    ah,0
  732.     cmp    ax,prepksz        ; same as previous packet?
  733.     je    pktsiz2            ; e = yes, skip display of size
  734.     push    ax
  735.     mov    dx,scrsz        ; position cursor
  736.     call    poscur
  737.     call    clearl            ; clear to end of line
  738.     pop    ax
  739.     mov    prepksz,ax        ; remember new value
  740.     add    ax,3            ; plus LEN, SEQ, TYPE
  741.     cmp    ax,94            ; larger than Regular?
  742.     jbe    pktsiz1            ; be = no
  743.     add    ax,3            ; add Long Packet len and chksum
  744. pktsiz1:call    decout            ; show packet length
  745.                     ; number of packets part
  746. pktsiz2:test    flags.remflg,dquiet    ; quiet screen?
  747.     jnz    pktsiz3            ; nz = yes
  748.     call    nppos            ; number of packets sent
  749.     mov    ax,numpkt        ; number of packets
  750.     call    nout            ; write the packet number
  751. pktsiz3:pop    si
  752.     pop    dx
  753.     pop    ax
  754.     ret
  755. PKTSIZE    ENDP
  756.  
  757. ; some random screen positioning functions
  758. kbpos:    mov    dx,scrkb        ; KBytes transferred
  759.     cmp    fmtdsp,0        ; formatted display?
  760.     jne    setup2            ; ne = yes
  761.     ret                ; else ignore postioning request
  762. perpos:    mov    dx,scrper        ; Percent transferred
  763.     cmp    fmtdsp,0        ; formatted display?
  764.     jne    setup2            ; ne = yes
  765.     ret                ; else ignore postioning request
  766. frpos:    mov    dx,scrmsg        ; say renamed file
  767.     jmp    short setup2
  768. stpos:    mov    dx,scrst        ; status of file transfer
  769.     jmp    short setup2
  770. nppos:    mov    dx,scrnp        ; Number of packets sent
  771.     cmp    fmtdsp,0        ; formatted display?
  772.     jne    setup2            ; ne = yes
  773.     ret
  774. rprpos:    test    flags.remflg,dserial+dquiet ; reprompt position
  775.     jnz    rprpos1            ; nz = no mode line for these
  776.     cmp    fmtdsp,0        ; formatted display?
  777.     je    rprpos1            ; e = no, so no mode line
  778.     call    clrmod            ; clear mode line
  779. rprpos1:mov    dx,scrrpr        ; Reprompt position
  780.     call    setup2            ; position cursor
  781.     mov    fmtdsp,0        ; turn off formatted display flag
  782.     ret
  783. sppos:    mov    dx,scrsp        ; Debug Send packet location
  784.     jmp    short setup1
  785. rppos:    mov    dx,scrrp        ; Debug Receive packet location
  786.     jmp    short setup1
  787.                 ; common service routines for positioning
  788. setup1:    test    flags.remflg,dquiet+dserial; quiet or serial display mode?
  789.     jnz    setupa            ; nz = yes
  790.     cmp    fmtdsp,0        ; non-formatted display?
  791.     je    setupa            ; e = yes
  792.     jmp    poscur
  793. setup2:    test    flags.remflg,dquiet+dserial; quiet or serial display mode?
  794.     jnz    setupa            ; nz = yes
  795.     cmp    fmtdsp,0        ; non-formatted display?
  796.     je    setupa            ; e = yes
  797.     call    poscur            ; no
  798.     jmp    clearl
  799. setupa: test    flags.remflg,dquiet    ; quiet mode?
  800.     jnz    setupx            ; nz = yes, do nothing
  801.     push    ax            ; display cr/lf and return
  802.     push    dx
  803.     mov    dx,offset crlf
  804.     mov    ah,prstr
  805.     int    dos
  806.     pop    dx
  807.     pop    ax
  808. setupx:    ret
  809.  
  810. ; Initialize formatted screen
  811.  
  812. INIT    PROC    NEAR
  813.     mov    windflag,0        ; init windows in use display flag
  814.     test    flags.remflg,dquiet    ; quiet display mode?
  815.     jnz    init4            ; nz = yes
  816.     test    flags.remflg,dserver    ; server mode?
  817.     jnz    init1            ; nz = yes
  818.     cmp    flags.xflg,0        ; destination is screen
  819.     jne    init4            ; ne = yes
  820. init1:    test    flags.remflg,dserial    ; serial mode display?
  821.     jnz    init3            ; nz = yes
  822.     call    cmblnk            ; clear the screen
  823.     mov    dx,offset cxzhlp
  824.     call    putmod            ; write mode line
  825.     mov    fmtdsp,1        ; say doing formatted display
  826.     test    flags.remflg,dserver    ; server mode?
  827.     jz    init2            ; z = no
  828.     mov    dx,scrser        ; move cursor to top of screen
  829.     call    poscur
  830.     mov    ah,prstr
  831.     mov    dx,offset infms1    ; say now in server mode
  832.     int    dos
  833. init2:    call    locate
  834.     mov    ah,prstr        ; put statistics headers on the screen
  835.     mov    dx,offset outlin1
  836.     int    dos
  837.     mov    dx,offset verident
  838.     int    dos
  839.     mov    dx,offset outlin2
  840.     int    dos
  841.     mov    wrpmsg,0        ; haven't printed the messsage yet
  842.     mov    prepksz,0        ; set previous packet size to zero
  843.     ret
  844. init3:    mov    ah,prstr
  845.     mov    dx,offset cxzser    ; status line as a text string
  846.     int    dos
  847. init4:    mov    wrpmsg,1        ; suppress display of percentage msg
  848.     mov    fmtdsp,0        ; say doing unformatted display
  849.     ret
  850. INIT    ENDP
  851.  
  852. ; show number of Kilobytes transferred
  853. ; modifies ax
  854. kbpr    proc    near
  855.     test    flags.remflg,dquiet    ; quiet display mode?
  856.     jnz    kbpr1            ; nz = yes, no printing
  857.     push    bx
  858.     mov    ax,tfilsz        ; low order word
  859.     mov    bx,tfilsz+2        ; high order word
  860.     add    ax,512            ; round up, add half the denominator
  861.     adc    bx,0
  862.     rcr    bx,1            ; divide double word by 1024,
  863.     rcr    ax,1            ; by dword shift right 10
  864.     rcr    bx,1
  865.     rcr    ax,1
  866.     mov    al,ah
  867.     mov    ah,bl            ; ax has the result
  868.     pop    bx
  869.     cmp    ax,oldkbt        ; is it the same?
  870.     je    kbpr1            ; yes, skip printing
  871.     mov    oldkbt,ax        ; save new # of kb
  872.     push    ax
  873.     call    kbpos            ; postion the cursor
  874.     pop    ax
  875.     call    decout            ; print number of KBytes transferred
  876. kbpr1:    ret
  877. kbpr    endp    
  878.  
  879. ; show percent transferred
  880. ; modifies ax
  881. perpr    proc    near
  882.     test    flags.remflg,dquiet    ; quiet display mode?
  883.     jz    perpr1            ; z = no. allow printing
  884.     ret                ; skip printing in remote mode
  885. perpr1:    cmp    diskio.sizehi,0        ; high word of original file size > 0 ?
  886.     jne    perpr3            ; ne = yes, use big file code
  887.     cmp    diskio.sizelo,0        ; anything here at all?
  888.     jne    perpr2            ; ne = yes, use small file code
  889.     ret                ; otherwise, quit now
  890. perpr2:    push    cx            ; case for files < 64 Kb
  891.     push    dx
  892.     mov    ax,diskio.sizelo    ; original size (low word)
  893.     mov    denom,ax
  894.     mov    dx,tfilsz+2        ;transferred size times 256 in [dx,ax]
  895.     mov    ax,tfilsz
  896.     mov    dh,dl            ; whole value multiplied by 256
  897.     mov    dl,ah
  898.     mov    ah,al
  899.     xor    al,al
  900.     mov    cx,denom        ; round up, add half the denominator
  901.     shr    cx,1
  902.     add    ax,cx
  903.     adc    dx,0
  904.     div    denom            ; (256*xfer)/orig. ax = quo, dx = rem
  905.     mul    onehun            ; multiply quotient above by 100
  906.     mov    al,ah            ; divide result (ax) by 256
  907.     xor    ah,ah            ; percentage is in ax
  908.     jmp    short perpr4        ; finish in common code
  909. perpr3:    push    cx            ; case for file size > 64 KB
  910.     push    dx
  911.     mov    ax,diskio.sizelo    ; original file size low order word
  912.     shr    ax,1            ; divide by 2
  913.     mov    al,ah            ; divide again by 256 for total of 512
  914.     xor    ah,ah            ; clear ah        
  915.     mov    dx,diskio.sizehi    ; high order word
  916.     xchg    dh,dl            ; do shl dx,cl=7
  917.     ror    dx,1            ; old low bit of dh to high bit of dh
  918.     and    dl,80h            ; clear lower bits. divided by two
  919.     or    ax,dx            ; paste together the two parts into ax
  920.     mov    denom,ax        ; denom = original size divided by 512
  921.     mov    dx,tfilsz+2        ; high order word of transferred size
  922.     mov    ax,tfilsz        ; low order word
  923.     mov    cx,denom        ; round up, add half the denominator
  924.     shr    cx,1
  925.     add    ax,cx
  926.     adc    dx,0
  927.     div    denom            ; xfer/(orig/512). ax=quot, dx=rem
  928.     mul    onehun            ; times 100 for 512*percentage, in ax
  929.     mov    al,ah            ; divide ax by 512
  930.     xor    ah,ah
  931.     shr    al,1            ; final percentage, in ax
  932. perpr4:    cmp    ax,oldper        ; same as it was before?
  933.     je    perpr7            ; yes, don't bother printing
  934.     mov    oldper,ax        ; remember this for next time
  935.     cmp    wrpmsg,0        ; did we write the percentage message?
  936.     jne    perpr5            ; ne = yes, skip this part
  937.     push    ax
  938.     call    perpos            ; position cursor
  939.     mov    dx,offset permsg
  940.     mov    ah,prstr
  941.     int    dos            ; write out message
  942.     pop    ax
  943.     mov    wrpmsg,1        ; init flag so we don't do it again
  944. perpr5: push    ax
  945.     call    perpos            ; position the cursor
  946.     pop    ax
  947.     cmp    ax,onehun        ; > 100% ?
  948.     jle    perpr6            ; no, accept it
  949.     mov    ax,onehun        ; else just use 100
  950. perpr6:    call    decout
  951.     mov    dl,25h            ; load a percent sign
  952.     mov    ah,conout        ; display the character
  953.     int    dos
  954. perpr7:    pop    dx
  955.     pop    cx
  956.     ret
  957. perpr    endp
  958.  
  959. winpr    proc    near            ; print number of active window slots
  960.     cmp    trans.windo,1        ; windowing in use?
  961.     jbe    winprx            ; be = no, no message
  962.     test    flags.remflg,dregular    ; regular display?
  963.     jz    winprx            ; z = no, no display
  964.     cmp    fmtdsp,0        ; formatted display?
  965.     je    winprx            ; e = no, no display here
  966.     test    flags.remflg,dserver    ; server mode?
  967.     jnz    winpr4            ; nz = yes, writing to their screen
  968.     cmp    flags.xflg,0        ; receiving to screen?
  969.     je    winpr4            ; e = no
  970. winprx:    ret
  971. winpr4:    push    ax
  972.     push    bx
  973.     push    cx
  974.     push    dx
  975.     push    si
  976.     cmp    windflag,0        ; have we written an initial value?
  977.     jne    winpr1            ; ne = yes
  978.     mov    dx,scrnp        ; position cursor
  979.     dec    dh
  980.     xor    dl,dl            ; 0 = left most column for text
  981.     call    poscur
  982.     call    clearl            ; clear the line
  983.     mov    ah,prstr
  984.     mov    dx,offset windmsg    ; the text
  985.     int    dos
  986.     xor    al,al            ; display an initial 0
  987.     mov    oldwind,-1
  988.     mov    windflag,1        ; say have done the work
  989.     jmp    short winpr2
  990. winpr1:    mov    al,windused        ; window slots in use
  991.     cmp    al,oldwind        ; same as before?
  992.     je    winpr3            ; e = yes, ignore
  993. winpr2:    push    ax
  994.     mov    dx,scrnp        ; position cursor
  995.     dec    dh
  996.     call    poscur
  997.     call    clearl
  998.     pop    ax
  999.     mov    oldwind,al        ; remember last value
  1000.     xor    ah,ah
  1001.     call    decout            ; display value
  1002.     mov    ah,prstr
  1003.     mov    dx,offset windmsg2    ; ' of '
  1004.     int    dos
  1005.     mov    al,trans.windo        ; number of window slots
  1006.     xor    ah,ah
  1007.     call    decout
  1008. winpr3:    pop    si
  1009.     pop    dx
  1010.     pop    cx
  1011.     pop    bx
  1012.     pop    ax
  1013.     ret
  1014. winpr    endp
  1015.  
  1016. code    ends
  1017.  
  1018. code1    segment
  1019.     assume    cs:code1
  1020.  
  1021. ; Start recording of statistics for this operation.
  1022. fbegtim    proc    FAR
  1023.     test    sflag,80h        ; is this a duplicate call?
  1024.     jz    begtim1            ; z = no
  1025.     ret                ; else just return
  1026. begtim1:push    ax
  1027.     push    cx
  1028.     push    dx
  1029.     push    di
  1030.     push    es
  1031.     push    ds
  1032.     pop    ds
  1033.     xor    ax,ax        ; clear statistics counters for this file
  1034.     cld
  1035.     mov    di,offset fsta.prbyte    ; start of the structure
  1036.     mov    cx,offset fsta.xstatus+1-offset fsta.prbyte ; end
  1037.     rep    stosb            ; clear most of the structure    [
  1038.     pop    es
  1039.     pop    di
  1040.     mov    ah,getdate        ; get current date, convert to ascii
  1041.     int    dos
  1042.     mov    date+9,'0'        ; init day of month
  1043. begtim2:cmp    dl,10            ; day of month. Ten or more days?
  1044.     jl    begtim3            ; l = no
  1045.     sub    dl,10
  1046.     inc    date+9            ; add up tens of days
  1047.     jmp    short begtim2        ; repeat for higher order
  1048. begtim3:add    dl,'0'            ; ascii bias
  1049.     mov    date+10,dl        ; day units
  1050.     mov    dl,dh            ; months (1-12)
  1051.     dec    dl            ; start at zero to index table
  1052.     xor    dh,dh
  1053.     mov    di,dx            ; months
  1054.     shl    di,1
  1055.     add    di,dx            ; times three chars/month
  1056.     mov    al,months[di]        ; get text string for month
  1057.     mov    date+12,al
  1058.     mov    ax,word ptr months[di+1]
  1059.     mov    word ptr date+13,ax
  1060.     mov    ax,cx            ; year since 1980
  1061.     mov    dx,0
  1062.     mov    di,offset date+16    ; destination
  1063.     call    flnout            ; convert number to asciiz in buffer
  1064.                     ; start time
  1065.     mov    ah,gettim        ; DOS time of day, convert to ascii
  1066.     int    dos
  1067.     mov    fsta.btime,dx        ; store ss.s   low word of seconds
  1068.     mov    fsta.btime+2,cx        ; store hhmm   high word of seconds
  1069.     mov    date,'0'        ; init begin hours field
  1070. begtim4:cmp    ch,10            ; ten or more hours?
  1071.     jl    begtim5            ; l = no
  1072.     sub    ch,10
  1073.     inc    date            ; add up tens of hours
  1074.     jmp    short begtim4        ; repeat for twenties
  1075. begtim5:add    ch,'0'            ; ascii bias
  1076.     mov    date+1,ch        ; store units of hours
  1077.     mov    date+3,'0'        ; minutes field
  1078. begtim6:cmp    cl,10            ; ten or more minutes?
  1079.     jl    begtim7            ; l = no
  1080.     sub    cl,10
  1081.     inc    date+3            ; add up tens of minutes
  1082.     jmp    short begtim6        ; repeat for higher orders
  1083. begtim7:add    cl,'0'            ; ascii bias
  1084.     mov    date+4,cl        ; store units of minutes
  1085.     mov    date+6,'0'        ; seconds field
  1086. begtim8:cmp    dh,10            ; ten or more seconds?
  1087.     jl    begtim9            ; l = no
  1088.     sub    dh,10
  1089.     inc    date+6            ; add up tens of seconds
  1090.     jmp    short begtim8        ; repeat for higher orders
  1091. begtim9:add    dh,'0'            ; ascii bias
  1092.     mov    date+7,dh
  1093.     mov    sflag,80h        ; say begtim has been run
  1094.     pop    dx
  1095.     pop    cx
  1096.     pop    ax
  1097.     ret
  1098. fbegtim    endp
  1099.  
  1100. ; Take snapshot of statistics counters at end of an operation
  1101. ; Enter with ax = 0 for a receive operation, ax = 1 for a send. [jrd]
  1102. fendtim    proc    FAR
  1103.     test    sflag,80h    ; called more than once without calling begtim?
  1104.     jnz    endtim1            ; ne = no, so do statistics snapshot
  1105.     ret                ; yes, do nothing
  1106. endtim1:and    sflag,not (1)        ; assume receive operation
  1107.     or    ax,ax            ; send (ax > 0), receive (ax = 0) flag
  1108.     jz    endtim2            ; z = receive opeation
  1109.     or    sflag,1            ; say send operation
  1110. endtim2:push    ax
  1111.     push    cx
  1112.     push    dx
  1113.     mov    ah,gettim        ; get DOS time of day
  1114.     int    dos
  1115.     mov    fsta.etime,dx        ; store ss. s
  1116.     mov    fsta.etime+2,cx        ; hhmm
  1117.     cmp    cx,fsta.btime+2        ; end time less than start time?
  1118.     ja    endtim2a    ; a = above (no need to test low order word)
  1119.     cmp    dx,fsta.btime        ; be. How about low order word
  1120.     jae    endtim2a        ; ae = no wrap around of time
  1121.     add    ch,24            ; add one day to hours field
  1122. endtim2a:sub    dl,byte ptr fsta.btime ; 0.01 sec difference
  1123.     jns    endtim2b
  1124.     dec    dh            ; borrow a second
  1125.     add    dl,100            ; make difference positive
  1126. endtim2b:sub    dh,byte ptr fsta.btime+1; seconds difference
  1127.     jns    endtim2c
  1128.     dec    cl            ; borrow a minute
  1129.     add    dh,60            ; make difference positive
  1130. endtim2c:xor    bh,bh
  1131.     mov    bl,dh            ; bx has seconds difference
  1132.     sub    cl,byte ptr fsta.btime+2 ; minutes
  1133.     jns    endtim2d
  1134.     dec    ch            ; borrow an hour
  1135.     add    cl,60
  1136. endtim2d:mov    al,cl
  1137.     xor    ah,ah
  1138.     mul    sixty            ; minutes to seconds
  1139.     add    bx,ax            ; seconds to bx
  1140.     sub    ch,byte ptr fsta.btime+3 ; hours difference
  1141.     jns    endtim2e
  1142.     add    ch,24
  1143. endtim2e:mov    al,ch
  1144.     xor    ah,ah
  1145.     mul    sixty            ; hours to minutes in ax
  1146.     mul    sixty            ; minutes to seconds in dx,ax
  1147.     add    ax,bx            ; ax = seconds
  1148.     adc    dx,0            ; dx = high word of seconds
  1149.     mov    fsta.etime,ax        ; store elapsed time, seconds, low wd
  1150.     mov    fsta.etime+2,dx        ; high word
  1151.     add    ssta.etime,ax        ; add to session time, low word
  1152.     adc    ssta.etime+2,dx        ; add to session time, high word
  1153.     mov    ax,fsta.pretry        ; retries for last transfer
  1154.     add    ssta.pretry,ax        ; retries for this session
  1155.  
  1156.     test    sflag,1            ; completing a receive operation?
  1157.     jnz    endtim3            ; nz = no, a send operation
  1158.     mov    ax,tfilsz        ; file bytes received, low word
  1159.     mov    fsta.frbyte,ax
  1160.     add    ssta.frbyte,ax        ; session received file bytes, low word
  1161.     mov    ax,tfilsz+2        ; high word
  1162.     mov    fsta.frbyte+2,ax
  1163.     adc    ssta.frbyte+2,ax
  1164.     jmp    short endtim4
  1165.  
  1166. endtim3:mov    ax,tfilsz        ; file bytes sent, low word
  1167.     mov    fsta.fsbyte,ax        ; file bytes sent
  1168.     add    ssta.fsbyte,ax        ; session sent file bytes, low word
  1169.     mov    ax,tfilsz+2        ; high word
  1170.     mov    fsta.fsbyte+2,ax
  1171.     adc    ssta.fsbyte+2,ax
  1172.  
  1173. endtim4:mov    ax,fsta.nakrcnt     ; NAKs received for this file
  1174.     add    ssta.nakrcnt,ax     ; session received NAKs
  1175.     mov    ax,fsta.nakscnt     ; NAKs sent for this file
  1176.     add    ssta.nakscnt,ax     ; session sent NAKs
  1177.                     ; do transaction logging
  1178.     cmp    tloghnd,0        ; logging transaction? -1 = not opened
  1179.     jg    endtim5            ; g = logging
  1180.     jmp    endtim12        ; skip logging
  1181. endtim5:push    di            ; kind of transaction
  1182.     push    bx            ; save these registers
  1183.     mov    bx,tloghnd        ; handle for transaction log
  1184.     mov    dx,offset rcvmsg    ; assume receive message
  1185.     test    sflag,1            ; 1 for send, 0 for receive
  1186.     jz    endtim6            ; z = receive
  1187.     mov    dx,offset sndmsg    ; send message
  1188. endtim6:call    fstrlen            ; length of message to cx
  1189.     mov    ah,write2
  1190.     int    dos            ; write kind of transfer
  1191.                     ; File names
  1192.     cmp    diskio.string,0        ; local filename
  1193.     je    endtim9            ; e = no filename
  1194.     test    sflag,1            ; a send operation?
  1195.     jnz    endtim8            ; nz = yes
  1196.                     ; Receive
  1197.     mov    dx,offset fsta.xname    ; remote name
  1198.     call    fstrlen            ; length to cx
  1199.     jcxz    endtim7            ; no name
  1200.     mov    ah,write2
  1201.     int    dos
  1202.     mov    dx,offset diskio.string    ; local name
  1203.     call    fstrlen            ; length to cx
  1204.     mov    si,offset fsta.xname    ; compare these two names
  1205.     mov    di,dx
  1206.     push    ds
  1207.     pop    es
  1208.     repe    cmpsb            ; compare
  1209.     je    endtim9            ; e = same, so no 'as' msg
  1210.     mov    dx,offset fasmsg    ; give 'as' message
  1211.     mov    cx,faslen        ; length
  1212.     mov    ah,write2
  1213.     int    dos
  1214. endtim7:mov    dx,offset diskio.string    ; local name
  1215.     call    fstrlen            ; get length
  1216.     mov    ah,write2        ; write local name
  1217.     int    dos
  1218.     jmp    short endtim9
  1219.  
  1220. endtim8:mov    dx,offset templp    ; Send. local name
  1221.     call    fstrlen
  1222.     mov    ah,write2
  1223.     int    dos
  1224.     cmp    fsta.xname,0        ; using an alias?
  1225.     je    endtim9            ; e = no
  1226.     mov    dx,offset fasmsg    ; give 'as' message
  1227.     mov    cx,faslen
  1228.     mov    ah,write2
  1229.     int    dos
  1230.     mov    dx,offset fsta.xname    ; get alias
  1231.     call    fstrlen
  1232.     mov    ah,write2
  1233.     int    dos
  1234.                     ; status of transfer
  1235. endtim9:mov    dx,offset atmsg        ; say At
  1236.     mov    cx,atlen        ; length
  1237.     mov    bx,tloghnd        ; handle
  1238.     mov    ah,write2
  1239.     int    dos
  1240.     mov    dx,offset date        ; write time and date field
  1241.     mov    cx,datelen        ; length
  1242.     mov    ah,write2
  1243.     int    dos
  1244.     mov    dx,offset fsucmsg    ; assume success message
  1245.     cmp    fsta.xstatus,kssuc    ; 0 = completed successfully?
  1246.     je    endtim10        ; e = completed
  1247.     mov    dx,offset fbadmsg    ; failed message
  1248.     test    fsta.xstatus,ksuser    ; user interrupted?
  1249.     jz    endtim10        ; z = no
  1250.     mov    dx,offset fintmsg    ; interrupted message
  1251. endtim10:call    fstrlen            ; get length to cx
  1252.     mov    ah,write2
  1253.     int    dos
  1254.                     ; file bytes transferred
  1255.     mov    ax,tfilsz        ; file bytes, low word
  1256.     mov    dx,tfilsz+2        ; high word
  1257.     mov    di,offset rdbuf        ; work buffer
  1258.     call    flnouts            ; transform to ascii
  1259.     mov    [di],0a0dh        ; append cr/lf
  1260.     add    di,2            ; count them
  1261.     mov    dx,offset rdbuf        ; start of work buffer
  1262.     mov    cx,di            ; next free byte
  1263.     sub    cx,dx            ; compute length
  1264.     mov    ah,write2
  1265.     int    dos
  1266.     cmp    dosnum,300h+30        ; DOS 3.30 or higher?
  1267.     jb    endtim11        ; b = no
  1268.     mov    ah,68h            ; Commit the file now
  1269.     int    dos
  1270. endtim11:pop    bx
  1271.     pop    di
  1272. endtim12:mov    tfilsz,0        ; clear file size area
  1273.     mov    tfilsz+2,0
  1274.     mov    sflag,0            ; say have done ending once already
  1275.     mov    fsta.xname,0        ; clear statistics "as" name
  1276.     pop    dx
  1277.     pop    cx
  1278.     pop    ax
  1279.     ret
  1280. fendtim    endp
  1281.  
  1282. fshosta    proc    far
  1283.     push    bx
  1284.     push    cx
  1285.     push    dx
  1286.     push    di
  1287.     mov    dx,offset statmsg    ; header
  1288.     mov    ah,prstr
  1289.     int    dos
  1290.     mov    dx,offset fchmsg    ; File characters msg
  1291.     mov    ah,prstr
  1292.     int    dos
  1293.     mov    di,offset ssta        ; session structure
  1294.     mov    bx,offset fsta        ; last file structure
  1295.     mov    ax,[bx].fsbyte        ; last transfer file bytes sent
  1296.     mov    dx,[bx].fsbyte+2
  1297.     mov    cx,12            ; field width
  1298.     call    shoprt            ; show result
  1299.     mov    ax,[bx].frbyte        ; last transfer file bytes received
  1300.     mov    dx,[bx].frbyte+2
  1301.     call    shoprt            ; show result
  1302.     mov    ax,[di].fsbyte        ; session file bytes sent
  1303.     mov    dx,[di].fsbyte+2
  1304.     call    shoprt            ; show result
  1305.     mov    ax,[di].frbyte        ; session file bytes received
  1306.     mov    dx,[di].frbyte+2
  1307.     call    shoprt            ; show result
  1308.  
  1309.     mov    ah,prstr
  1310.     mov    dx,offset spmsg        ; serial port material
  1311.     int    dos
  1312.     mov    ax,[bx].psbyte        ; last transfer port bytes sent
  1313.     mov    dx,[bx].psbyte+2
  1314.     call    shoprt            ; show result
  1315.     mov    ax,[bx].prbyte        ; last transfer port bytes received
  1316.     mov    dx,[bx].prbyte+2
  1317.     call    shoprt            ; show result
  1318.     mov    ax,[di].psbyte        ; session port bytes sent
  1319.     mov    dx,[di].psbyte+2
  1320.     call    shoprt            ; show result
  1321.     mov    ax,[di].prbyte        ; session port bytes received
  1322.     mov    dx,[di].prbyte+2
  1323.     call    shoprt            ; show result
  1324.  
  1325.     mov    dx,offset pktmsg    ; packets material
  1326.     mov    ah,prstr
  1327.     int    dos
  1328.     mov    ax,[bx].pspkt        ; last transfer packets sent
  1329.     mov    dx,[bx].pspkt+2
  1330.     call    shoprt            ; show result
  1331.     mov    ax,[bx].prpkt        ; last transfer packets received
  1332.     mov    dx,[bx].prpkt+2
  1333.     call    shoprt            ; show result
  1334.     mov    ax,[di].pspkt        ; session packets sent
  1335.     mov    dx,[di].pspkt+2
  1336.     call    shoprt            ; show result
  1337.     mov    ax,[di].prpkt        ; session packets received
  1338.     mov    dx,[di].prpkt+2
  1339.     call    shoprt            ; show result
  1340.  
  1341.     mov    dx,offset nakmsg    ; NAKs material
  1342.     mov    ah,prstr
  1343.     int    dos
  1344.     mov    ax,[bx].nakscnt        ; last transfer NAKs sent
  1345.     xor    dx,dx
  1346.     call    shoprt
  1347.     mov    ax,[bx].nakrcnt        ; last transfer NAKs received
  1348.     xor    dx,dx
  1349.     call    shoprt
  1350.     mov    ax,[di].nakscnt        ; session NAKs sent
  1351.     xor    dx,dx
  1352.     call    shoprt
  1353.     mov    ax,[di].nakrcnt        ; session NAKs received
  1354.     xor    dx,dx
  1355.     call    shoprt
  1356.  
  1357.     mov    dx,offset retmsg    ; retries
  1358.     mov    ah,prstr
  1359.     int    dos
  1360.     mov    ax,[bx].pretry        ; last transfer retry count
  1361.     xor    dx,dx
  1362.     mov    cx,18
  1363.     call    shoprt
  1364.     mov    ax,[di].pretry        ; session retries
  1365.     xor    dx,dx
  1366.     mov    cx,24
  1367.     call    shoprt
  1368.  
  1369.     mov    dx,offset timemsg    ; elapsed time material
  1370.     mov    ah,prstr
  1371.     int    dos
  1372.     mov    ax,[bx].etime        ; elapsed time of last transfer
  1373.     mov    dx,[bx].etime+2
  1374.     mov    cx,18
  1375.     call    shoprt            ; show result
  1376.     mov    ax,[di].etime        ; elapsed time of session
  1377.     mov    dx,[di].etime+2
  1378.     mov    cx,24
  1379.     call    shoprt            ; show result
  1380.  
  1381.     mov    dx,offset chpsmsg    ; File chars per second
  1382.     mov    ah,prstr
  1383.     int    dos
  1384.     mov    ax,[bx].frbyte        ; file bytes received, low
  1385.     mov    dx,[bx].frbyte+2    ; file bytes received, high
  1386.     add    ax,[bx].fsbyte        ; file bytes sent, low
  1387.     adc    dx,[bx].fsbyte+2    ;  high. [dx,ax] = total file bytes
  1388.     call    showrk            ; do worker
  1389.     xor    dx,dx            ; discard the fractional cps
  1390.     mov    cx,18
  1391.     call    shoprt            ; show result
  1392.     xchg    bx,di            ; swap session and last file pointers
  1393.     mov    ax,[bx].frbyte        ; file bytes received, low
  1394.     mov    dx,[bx].frbyte+2    ; file bytes received, high
  1395.     add    ax,[bx].fsbyte        ; file bytes sent, low
  1396.     adc    dx,[bx].fsbyte+2    ;  high. [dx,ax] = total file bytes
  1397.     call    showrk            ; do worker
  1398.     xchg    bx,di            ; unswap session and last file pointers
  1399.     xor    dx,dx            ; discard the fractional cps
  1400.     mov    cx,24
  1401.     call    shoprt            ; show result
  1402.         
  1403.     mov    dx,offset spedmsg    ; speed material
  1404.     mov    ah,prstr
  1405.     int    dos
  1406.         ; compute baud rate as  10 * total port bytes / elapsed time
  1407.     mov    ax,[bx].prbyte        ; port bytes received, low
  1408.     mov    dx,[bx].prbyte+2    ; port bytes received, high
  1409.     add    ax,[bx].psbyte        ; port bytes sent, low
  1410.     adc    dx,[bx].psbyte+2    ;  high. [dx,ax] = total port bytes
  1411.     call    showrk            ; do worker for bytes/sec and fraction
  1412.     mov    cx,dx            ; save remainder of bytes/second
  1413.     mul    ten            ; bytes/sec times ten to dx,ax
  1414.     push    dx            ; save high order part
  1415.     push    ax            ; save partial baud rate
  1416.     mov    ax,cx            ; remainder to ax
  1417.     xor    dx,dx            ; clear extension
  1418.     mul    ten        ; remainder times ten too (keep only overflow)
  1419.     mov    cx,dx            ; overflow part
  1420.     pop    ax            ; recover main partial result
  1421.     pop    dx            ; high order part
  1422.     add    ax,cx            ; add two partial results
  1423.     adc    dx,0            ; add to extension
  1424.     mov    cx,18
  1425.     call    shoprt            ; show result
  1426.     xchg    bx,di            ; swap session and last file pointers
  1427.     mov    ax,[bx].prbyte        ; port bytes received, low
  1428.     mov    dx,[bx].prbyte+2    ; port bytes received, high
  1429.     add    ax,[bx].psbyte        ; port bytes sent, low
  1430.     adc    dx,[bx].psbyte+2    ;  high. [dx,ax] = total port bytes
  1431.     mov    bx,offset ssta
  1432.     call    showrk            ; do worker for bytes/sec and fraction
  1433.     mov    cx,dx            ; save remainder of bytes/second
  1434.     mul    ten            ; bytes/sec times ten to dx,ax
  1435.     push    dx            ; save high order part
  1436.     push    ax            ; save partial baud rate
  1437.     mov    ax,cx            ; remainder to ax
  1438.     xor    dx,dx            ; clear extension
  1439.     mul    ten        ; remainder times ten too (keep only overflow)
  1440.     mov    cx,dx            ; overflow part
  1441.     pop    ax            ; recover main partial result
  1442.     pop    dx            ; high order part
  1443.     add    ax,cx            ; add two partial results
  1444.     adc    dx,0            ; add to extension
  1445.     mov    cx,24
  1446.     call    shoprt            ; show result
  1447.  
  1448.     mov    ah,prstr
  1449.     mov    dx,offset crlf
  1450.     int    dos
  1451.     pop    di
  1452.     pop    dx
  1453.     pop    cx
  1454.     pop    bx
  1455.     clc
  1456.     ret
  1457. fshosta    endp
  1458.  
  1459. ; Display SHOW STATISTICS line. Enter with dx,ax with long value, cx = width
  1460. shoprt    proc    near
  1461.     push    di
  1462.     mov    di,offset rdbuf        ; work space for output
  1463.     call    flnouts            ; show long integer, with separator
  1464.     pop    di
  1465.     mov    dx,offset rdbuf
  1466.     push    bx
  1467.     push    cx
  1468.     push    dx
  1469.     mov    bx,cx            ; field width
  1470.     call    fstrlen            ; length of string in dx
  1471.     sub    bx,cx            ; number of spaces necessary
  1472.     xchg    bx,cx
  1473.     jle    shoprt2            ; le = no spaces
  1474.     mov    dl,' '
  1475.     mov    ah,conout
  1476. shoprt1:int    dos            ; display the leading spaces
  1477.     loop    shoprt1
  1478. shoprt2:pop    dx
  1479.     pop    cx
  1480.     pop    bx
  1481.     call    fprtasz            ; display asciiz string
  1482.     ret
  1483. shoprt    endp
  1484.  
  1485. ; baud rate and char/sec worker for above
  1486. ; Enter with dx,ax holding the byte count, returns (dx,ax / seconds in
  1487. ; ax (whole number) and dx (fraction).
  1488. showrk    proc    near    
  1489.     mov    cx,[bx].etime        ; low word of sec in cx
  1490.     cmp    [bx].etime+2,0    ; is high word of sec zero (e.t. < 65536 sec)?
  1491.     jz    showrk1            ; z = yes, ready for arithmetic
  1492.     push    ax            ; else scale values, save byte count
  1493.     push    dx
  1494.     mov    ax,[bx].etime        ; elapsed time for file, low word
  1495.     mov    dx,[bx].etime+2        ;  high word    
  1496.     shr    ax,1            ; divide seconds by two, low word
  1497.     ror    dx,1            ; get low bit of high word
  1498.     and    dx,8000            ; pick out just that bit
  1499.     or    ax,dx        ; mask in that bit, new time in ax (dx = 0)
  1500.     mov    cx,ax            ; save elapsed time (double-seconds)
  1501.     pop    dx            ; get byte count again
  1502.     pop    ax
  1503.     shr    ax,1            ; divide byte count by two also
  1504.     push    dx
  1505.     ror    dx,1            ; rotate low bit to high position
  1506.     and    dx,8000h        ; get low bit of high word
  1507.     or    ax,dx            ; byte count divided by two, low word
  1508.     pop    dx
  1509.     shr    dx,1            ; and high word
  1510. showrk1:or    cx,cx               ; is elapsed time (in cx) zero seconds?
  1511.     jnz    showrk2            ; nz = no
  1512.     inc    cx                ; set time to one second (no div by 0)
  1513. showrk2:div    cx               ; bytes div seconds, ax = quo, dx = rem
  1514.     ret
  1515. showrk    endp
  1516.  
  1517.  
  1518. fshomdef proc    FAR            ; worker, show mac name and def
  1519.     push    ax            ; call with si pointing at macro
  1520.     push    si            ; name, word ptr [si-2] = length
  1521.     push    es
  1522.     cmp    byte ptr[si],0        ; name starts with null char?
  1523.     jne    shomd1            ; ne = no
  1524.     jmp    shomd9            ; yes, TAKE file, ignore
  1525. shomd1:    call    shomdl            ; do newline, check for more/exit
  1526.     jnc    shomd2            ; nc = continue
  1527.     jmp    shomd9            ; exit
  1528. shomd2:    mov    ah,conout
  1529.     mov    dl,' '            ; add a space
  1530.     int    dos
  1531.     inc    bx
  1532.     inc    temp            ; count displayed macros
  1533.     push    cx
  1534.     push    di
  1535.     mov    cx,[si-2]        ; length of definition
  1536.     mov    di,si            ; offset for printing
  1537.     call    fprtscr            ; print counted string
  1538.     pop    di
  1539.     pop    cx
  1540.     mov    ah,prstr
  1541.     mov    dx,offset eqs        ; display equals sign
  1542.     int    dos
  1543.     mov    denom,1            ; set flag to do "," to <cr>
  1544.     cmp    word ptr [si],'%\'    ; substitution variable?
  1545.     jne    shomd2a            ; ne = no
  1546.     mov    denom,0            ; clear bare comma sensitivity flag
  1547. shomd2a:mov    ax,[si-2]        ; length of macro name
  1548.     add    si,ax            ; skip over name
  1549.     add    bx,ax            ; count of chars on line
  1550.     add    bx,3            ; plus " = "
  1551.     mov    es,[si]            ; segment of string structure
  1552.     xor    si,si            ; es:si = address of count + string
  1553.     mov    cx,es:[si]        ; length of string
  1554.     add    si,2            ; si = offset of string text proper
  1555. shomd3:    mov    al,es:[si]        ; get a byte into al
  1556.     inc    si
  1557.     call    shombrk            ; examine for bare comma break
  1558.     cmp    al,' '            ; control char?
  1559.     jae    shomd5            ; ae = no
  1560.     cmp    al,cr            ; carriage return?
  1561.     jne    shomd4            ; ne = no
  1562.     mov    ah,prstr
  1563.     mov    dx,offset shom9m4    ; show <cr>
  1564.     int    dos
  1565.     add    bx,4            ; chars on line
  1566.     cmp    cx,1            ; more to show?
  1567.     je    shomd6            ; e = no
  1568.     call    shomdl            ; new line, check for continue or exit
  1569.     jc    shomd9            ; c = exit
  1570.     mov    ah,conout        ; show two spaces
  1571.     mov    dl,' '            ; the spaces
  1572.     int    dos
  1573.     int    dos
  1574.     add    bx,2
  1575.     cmp    byte ptr es:[si],lf    ; cr followed by linefeed?
  1576.     jne    short shomd6        ; ne = no
  1577.     inc    si            ; skip the leading lf
  1578.     dec    cx
  1579.     jmp    short shomd6
  1580. shomd4:    push    ax
  1581.     mov    ah,conout
  1582.     mov    dl,5eh            ; caret
  1583.     int    dos
  1584.     pop    ax
  1585.     inc    bx
  1586.     add    al,'A'-1        ; add offset to make printable letter
  1587. shomd5:    mov    ah,conout
  1588.     mov    dl,al            ; display it
  1589.     int    dos
  1590.     inc    bx
  1591. shomd6:    cmp    bx,75            ; time to break the line?
  1592.     jb    shomd8            ; b = no
  1593.     cmp    bx,76            ; at an absolute break point
  1594.     jae    shomd7            ; ae = yes
  1595.     cmp    byte ptr es:[si],' '    ; is next char a space?
  1596.     je    shomd8            ; e = yes, show explicitly
  1597. shomd7:    mov    ah,conout        ; display a line break hyphen
  1598.     mov    dl,'-'
  1599.     int    dos
  1600.     call    shomdl            ; check for screen full
  1601.     jc    shomd9            ; c = exit now
  1602.     mov    ah,conout        ; show two spaces
  1603.     xor    bx,bx            ; column counter
  1604. shomd8:    loop    shomd3            ; do whole string
  1605. shomd9:    pop    es
  1606.     pop    si
  1607.     pop    ax
  1608.     ret
  1609.                       ; worker, do "more" and Control-C checking
  1610. shomdl    proc    near
  1611.     inc    temp1            ; count lines displayed
  1612.     xor    bx,bx            ; count of chars on the line
  1613.     cmp    temp1,24        ; done a normal screens' worth?
  1614.     jb    shomdl2            ; b = no
  1615.     mov    ah,prstr
  1616.     mov    dx,offset moremsg    ; say more
  1617.     int    dos
  1618.     mov    temp1,0
  1619.     mov    flags.cxzflg,0        ; clear flag so we can see Control-C
  1620.     mov    ah,0ch            ; clear keyboard buffer
  1621.     mov    al,coninq        ; quiet input
  1622.     int    dos
  1623.     cmp    al,3            ; Control-C?
  1624.     je    shomdl1            ; e = yes
  1625.     cmp    al,'q'            ; q for quit?
  1626.     je    shomdl1            ; e = yes
  1627.     cmp    al,'Q'            ; Q for quit?
  1628.     je    shomdl1            ; e = yes
  1629.     or    al,al            ; scan code?
  1630.     jne    shomdl2            ; ne = no
  1631.     mov    ah,coninq        ; read the second byte
  1632.     int    dos
  1633.     or    al,al            ; null for Control-Break?
  1634.     jne    shomdl2            ; ne = no
  1635. shomdl1:mov    flags.cxzflg,'C'    ; say want to exit now
  1636. shomdl2:mov    ah,prstr
  1637.     mov    dx,offset crlf
  1638.     int    dos
  1639.     cmp    flags.cxzflg,0        ; want to exit?
  1640.     jne    shomdl3            ; ne = yes
  1641.     clc
  1642.     ret
  1643. shomdl3:stc                ; say exit now
  1644.     ret
  1645. shomdl    endp
  1646.  
  1647. ; Examine char in al. If it is a bare comma and byte ptr denom is non-zero
  1648. ; then change AL to Carriage return else return AL unchanged.
  1649. shombrk    proc    near
  1650.     push    dx
  1651.     mov    dx,denom        ; dh=brace cnt, dl=1 for sensitivity
  1652.     or    dl,dl            ; worry about bare commas?
  1653.     jz    shombr3            ; z = no
  1654.     cmp    al,braceop        ; opening brace?
  1655.     jne    shombr1            ; ne = no
  1656.     inc    dh            ; count brace level
  1657. shombr1:cmp    al,bracecl        ; closing brace?
  1658.     jne    shombr2
  1659.     sub    dh,1            ; count down brace level
  1660.     jns    shombr2            ; ns = not below zero
  1661.     xor    dh,dh            ; set brace level to zero
  1662. shombr2:mov    denom,dx        ; store our brace state
  1663.     or    dh,dh            ; inside braces?
  1664.     jnz    shombr3            ; nz = yes
  1665.     cmp    al,','            ; bare comma?
  1666.     jne    shombr3            ; ne = no
  1667.     mov    al,CR            ; replace with bare CR
  1668. shombr3:pop    dx
  1669.     ret
  1670. shombrk    endp
  1671. fshomdef endp
  1672.  
  1673. fshovar    proc    FAR            ; worker for SHOW VARIABLE, SHOVAR
  1674.     cmp    word ptr rdbuf,'v\'    ; did user say \v(name)?
  1675.     jne    fshova2            ; ne = no
  1676.     mov    di,offset rdbuf        ; start plus count
  1677.     mov    si,di
  1678.     add    si,3            ; remove \v(
  1679.     mov    cx,shmcnt        ; length of user spec
  1680.     sub    cx,3
  1681.     mov    shmcnt,cx        ; remember "variable)" part
  1682.     jle    fshova1            ; le = nothing left
  1683.     inc    cx            ; include null in the move
  1684.     mov    ax,ds
  1685.     mov    es,ax
  1686.     cld
  1687.     rep    movsb            ; copy down
  1688.     mov    si,offset rdbuf
  1689.     add    si,shmcnt
  1690.     cmp    byte ptr [si-1],')'    ; did user say ')'?
  1691.     jne    fshova2            ; ne = no
  1692.     mov    byte ptr [si-1],0    ; remove it
  1693.     dec    shmcnt
  1694.     jmp    short fshova2
  1695. fshova1:mov    shmcnt,0        ; make user entry empty
  1696. fshova2:mov    si,offset valtab    ; table of variable names
  1697.     cld
  1698.     lodsb
  1699.     mov    cl,al            ; number of variable entries
  1700.     xor    ch,ch
  1701.     jcxz    fshova7            ; z = none
  1702. fshova3:push    cx            ; save loop counter
  1703.     lodsw                ; length of var name, incl ')'
  1704.     mov    cx,shmcnt        ; length of user's string
  1705.     jcxz    fshova5            ; show all names
  1706.     push    ax            ; save length
  1707.     dec    ax            ; omit ')'
  1708.     cmp    ax,cx            ; var name shorter that user spec?
  1709.     pop    ax            ; recover full length
  1710.     jb    fshova6            ; b = yes, no match
  1711.     push    ax
  1712.     push    si            ; save these around match test
  1713.     mov    di,offset rdbuf        ; user's string
  1714. fshova4:mov    ah,[di]
  1715.     inc    di
  1716.     lodsb                ; al = var name char, ah = user char
  1717.     and    ax,not 2020h        ; clear bits (uppercase chars)
  1718.     cmp    ah,al            ; same?
  1719.     loope    fshova4            ; while equal, do more
  1720.     pop    si            ; restore regs
  1721.     pop    ax
  1722.     jne    fshova6            ; ne = no match
  1723. fshova5:call    fshova8            ; show this name
  1724. fshova6:add    si,ax            ; point to next name, add name length
  1725.     add    si,2            ; and string pointer
  1726.     pop    cx            ; recover loop counter
  1727.     cmp    flags.cxzflg,0        ; does user wish to stop now?
  1728.     jne    fshova7            ; ne = yes
  1729.     loop    fshova3            ; one less macro to examine
  1730. fshova7:mov    flags.cxzflg,0        ; clear flag before exiting
  1731.     ret
  1732.  
  1733. fshova8    proc    near            ; worker for above
  1734.     push    ax
  1735.     mov    ah,prstr
  1736.     mov    dx,offset varstng    ; put out <cr><lf>" \v("
  1737.     int    dos
  1738.     push    si
  1739.     push    cx
  1740.     mov    cx,[si-2]        ; length of name
  1741. fshova9:mov    dl,[si]            ; get a variable character
  1742.     inc    si            ; prep for next char
  1743.     mov    ah,conout
  1744.     int    dos
  1745.     loop    fshova9            ; do the count
  1746.     mov    dl,' '            ; display " = "
  1747.     int    dos
  1748.     mov    dl,'='
  1749.     int    dos
  1750.     mov    dl,' '
  1751.     int    dos
  1752.     mov    bx,[si]            ; get result code to bx
  1753.     xor    dx,dx            ; trim off trailing spaces
  1754.     call    fnvaltoa        ; fill valbuf with string
  1755.     jc    fshova10        ; c = failure
  1756.     mov    cx,di            ; di is string length
  1757.     mov    di,offset valbuf+2    ; string text (skips count word)
  1758.     call    fprtscr            ; display counted string
  1759. fshova10:pop    cx
  1760.     pop    si
  1761.     pop    ax
  1762.     ret
  1763. fshova8    endp                ; end of worker
  1764. fshovar    endp
  1765.  
  1766. code1    ends
  1767.  
  1768. code    segment
  1769.     assume cs:code
  1770.  
  1771. ; SHOW TRANSLATE-RECEIVE
  1772. ; Display characters being changed for Connect mode serial receive translator
  1773.  
  1774. SHORX    PROC    NEAR            ; show translate table of incoming
  1775.                     ; chars, only those changed
  1776.     mov    ah,cmeol        ; get a confirm
  1777.     call    comnd
  1778.     jnc    shorx0a            ; nc = success
  1779.     ret                ; failure
  1780. shorx0a:
  1781.     mov    ah,prstr
  1782.     mov    dx,offset crlf
  1783.     int    dos
  1784.     mov    bx,offset shorxk    ; show keyboard translation
  1785.     call    statc
  1786.     mov    ah,prstr
  1787.     mov    dx,offset rxoffmsg    ; assume translation is off
  1788.     cmp    rxtable+256,0        ; is translation off?
  1789.     je    shorx0            ; e = yes
  1790.     mov    dx,offset rxonmsg    ; say translation is on
  1791. shorx0:    int    dos
  1792.     mov    dx,offset shormsg    ; give title line
  1793.     int    dos
  1794.     xor    cx,cx            ; formatted line counter
  1795.     xor    bx,bx            ; entry subscript
  1796. shorx1:    cmp    rxtable[bx],bl        ; entry same as normal?
  1797.     je    shorx2            ; e = yes, skip it
  1798.     call    shorprt            ; display the entry
  1799. shorx2:    inc    bx            ; next entry
  1800.     cmp    bx,255            ; done all entries yet?
  1801.     jbe    shorx1            ; be = not yet
  1802.     mov    ah,prstr
  1803.     mov    dx,offset crlf        ; end with cr/lf
  1804.     int    dos
  1805.     clc                ; success
  1806.     ret
  1807.                     ; worker routine
  1808. shorprt:cmp    cx,4            ; done five entries for this line?
  1809.     jb    shorpr1            ; b = no
  1810.     mov    ah,prstr
  1811.     mov    dx,offset crlf        ; break line now
  1812.     int    dos
  1813.     xor    cx,cx
  1814. shorpr1:mov    ah,prstr
  1815.     mov    dx,offset shopm1    ; start of display
  1816.     int    dos
  1817.     xor    ah,ah
  1818.     mov    al,bl            ; original byte code
  1819.     call    decout            ; display its value
  1820.     mov    ah,prstr
  1821.     mov    dx,offset shopm2    ; intermediate part of display
  1822.     int    dos
  1823.     xor    ah,ah
  1824.     mov    al,rxtable[bx]        ; new byte code
  1825.     call    decout            ; display its value
  1826.     mov    ah,prstr
  1827.     mov    dx,offset shopm3    ; last part of display
  1828.     int    dos
  1829.     inc    cx            ; count item displayed
  1830.     ret
  1831. SHORX    ENDP
  1832.  
  1833. ; SHOW MACRO [macro name]
  1834.  
  1835. SHOMAC    PROC    NEAR
  1836.     mov    ah,cmword
  1837.     mov    dx,offset rdbuf
  1838.     mov    bx,offset shmmsg
  1839.     mov    comand.cmper,1        ; don't react to \%x variables
  1840.     call    comnd
  1841.     jnc    shoma1a            ; nc = success
  1842.     ret                ; failure
  1843. shoma1a:mov    shmcnt,ax        ; save length of user spec
  1844.     mov    ah,cmeol
  1845.     call    comnd
  1846.     jnc    shoma1b            ; nc = success
  1847.     ret                ; failure
  1848. shoma1b:mov    si,offset mcctab    ; table of macro names
  1849.     cld
  1850.     lodsb
  1851.     mov    cl,al            ; number of macro entries
  1852.     xor    ch,ch
  1853.     jcxz    shom6            ; z = none
  1854.     mov    temp,0            ; count of macros displayed
  1855.     mov    temp1,0            ; lines displayed, for more message
  1856. shom2:    push    cx            ; save loop counter
  1857.     lodsw                ; length of macro name
  1858.     mov    cx,shmcnt        ; length of user's string
  1859.     jcxz    shom4            ; show all names
  1860.     cmp    ax,cx            ; mac name shorter that user spec?
  1861.     jb    shom5            ; b = yes, no match
  1862.     push    ax
  1863.     push    si            ; save these around match test
  1864.     mov    di,offset rdbuf        ; user's string
  1865. shom3:    mov    ah,[di]
  1866.     inc    di
  1867.     lodsb                ; al = mac name char, ah = user char
  1868.     and    ax,not 2020h        ; clear bits (uppercase chars)
  1869.     cmp    ah,al            ; same?
  1870.     loope    shom3            ; while equal, do more
  1871.     pop    si            ; restore regs
  1872.     pop    ax
  1873.     jne    shom5            ; ne = no match
  1874. shom4:    call    fshomdef        ; show this name (FAR)
  1875. shom5:    add    si,ax            ; point to next name, add name length
  1876.     add    si,2            ;  and string pointer
  1877.     pop    cx            ; recover loop counter
  1878.     cmp    flags.cxzflg,0        ; does user wish to stop now?
  1879.     jne    shom5a            ; ne = yes
  1880.     loop    shom2            ; one less macro to examine
  1881. shom5a:    mov    flags.cxzflg,0        ; clear flag before exiting
  1882.     cmp    temp,0            ; did we show any macros?
  1883.     jne    shom7            ; ne = yes
  1884. shom6:    mov    ah,prstr
  1885.     mov    dx,offset shom9m3    ; no entries found
  1886.     int    dos
  1887. shom7:    mov    ah,prstr        ; Summary line
  1888.     mov    dx,offset shom9m1    ; free space: name entries
  1889.     int    dos
  1890.     mov    ax,offset mcctab+mcclen
  1891.     sub    ax,mccptr        ; compute # of free name bytes
  1892.     call    decout
  1893.     mov    ah,prstr
  1894.     mov    dx,offset crlf
  1895.     int    dos
  1896.     clc                ; success
  1897.     ret
  1898. SHOMAC    ENDP
  1899.  
  1900. SHCOM    PROC    NEAR            ; Show Modem
  1901.     mov    ah,cmeol
  1902.     call    comnd            ; get a confirm
  1903.     jc    shcom1            ; c = failure
  1904.     mov    dx,offset crlf
  1905.     mov    ah,prstr
  1906.     int    dos            ; print a crlf
  1907.     mov    bx,offset stcom        ; table of items to be shown
  1908.     call    statc            ; finish in common code
  1909.     call    shomodem
  1910.     clc
  1911. shcom1:    ret
  1912. SHCOM    ENDP
  1913.  
  1914. SHFILE    PROC    NEAR            ; Show File
  1915.     mov    ah,cmeol
  1916.     call    comnd            ; get a confirm
  1917.     jnc    shfile1            ; nc = success
  1918.     ret                ; failure
  1919. shfile1:mov    dx,offset crlf
  1920.     mov    ah,prstr
  1921.     int    dos            ; print a crlf
  1922.     mov    bx,offset stfile    ; table of items to be shown
  1923.     jmp    statc            ; finish in common code
  1924. SHFILE    ENDP
  1925.  
  1926. SHLOG    PROC    NEAR            ; Show Log
  1927.     mov    ah,cmeol
  1928.     call    comnd            ; get a confirm
  1929.     jnc    shlog1            ; nc = success
  1930.     ret                ; failure
  1931. shlog1:    mov    dx,offset crlf
  1932.     mov    ah,prstr
  1933.     int    dos            ; print a crlf
  1934.     mov    bx,offset stlog        ; table of items to be shown
  1935.     jmp    statc            ; finish in common code
  1936. SHLOG    ENDP
  1937.  
  1938. SHMEM    PROC    NEAR            ; Show (free) Memory.   Recursive!
  1939.     mov    ah,cmeol
  1940.     call    comnd            ; get a confirm
  1941.     jnc    shmem1            ; nc = success
  1942.     ret                ; failure
  1943. shmem1:    mov    ah,prstr
  1944.     mov    dx,offset memmsg1    ; header message
  1945.     int    dos
  1946.     mov    word ptr rdbuf,'  '    ; two spaces
  1947.     mov    rdbuf+2,0        ; safety null terminator
  1948.     mov    di,offset rdbuf+1    ; look at first space
  1949.     mov    temp,0            ; total free memory
  1950.     mov    temp1,0            ;  and high word thereof
  1951.     push    es            ; save es
  1952.     call    shmem4            ; allocate memory, recursively
  1953.     mov    dx,offset rdbuf        ; output buffer
  1954.     call    prtasz            ; show pieces
  1955.     mov    dx,offset memmsg2    ; trailer
  1956.     mov    ah,prstr
  1957.     int    dos
  1958.     mov    di,offset rdbuf        ; setup buffer for lnout
  1959.     mov    rdbuf,0
  1960.     mov    ax,temp            ; total free space
  1961.     mov    dx,temp1
  1962.     call    lnouts            ; 32 bit to decimal ascii in di
  1963.     mov    dx,offset rdbuf        ;  with thousands separator
  1964.     call    prtasz
  1965.     pop    es
  1966.     ret
  1967.                     ; worker routine
  1968. shmem4:    mov    bx,0ffffh        ; allocate all memory (must fail)
  1969.     mov    ah,alloc        ; DOS memory allocator
  1970.     int    dos            ; returns available paragraphs in bx
  1971.     jnc    shmem6            ; nc = got it all (not very likely)
  1972.     or    bx,bx            ; bx = # paragraphs alloc'd. Anything?
  1973.     jz    shmem5            ; z = no
  1974.     mov    ah,alloc        ; consume qty now given in bx
  1975.     int    dos
  1976.     jnc    shmem6            ; nc = got the fragment
  1977. shmem5:    ret
  1978. shmem6:    push    ax            ; save allocation segment
  1979.     mov    ax,bx            ; convert paragraphs
  1980.     mul    sixteen            ;  to bytes in dx:ax
  1981.     add    temp,ax            ; running total
  1982.     adc    temp1,dx        ;  32 bits
  1983.     cmp    byte ptr [di],0        ; starting on a null?
  1984.     jne    shmem7            ; ne = no, skip punctuation
  1985.     mov    byte ptr [di],'+'    ; plus punctuation
  1986.     inc    di
  1987. shmem7:    call    lnouts            ; long number to decimal in buffer di
  1988.     call    shmem4            ; recurse
  1989.     pop    es            ; recover allocation segment
  1990.     mov    ah,freemem        ; free the allocation
  1991.     int    dos
  1992.     ret
  1993. SHMEM    ENDP
  1994.  
  1995. SHPRO    PROC    NEAR            ; Show Protocol
  1996.     mov    ah,cmeol
  1997.     call    comnd            ; get a confirm
  1998.     jnc    shpro1            ; nc = success
  1999.     ret                ; failure
  2000. shpro1:    mov    dx,offset crlf
  2001.     mov    ah,prstr
  2002.     int    dos            ; print a crlf
  2003.     mov    bx,offset stpro        ; table of items to be shown
  2004.     jmp    statc            ; finish in common code
  2005. SHPRO    ENDP
  2006.  
  2007. SHSCPT    PROC    NEAR            ; Show Script
  2008.     mov    ah,cmeol
  2009.     call    comnd            ; get a confirm
  2010.     jnc    shscpt1            ; nc = success
  2011.     ret                ; failure
  2012. shscpt1:mov    dx,offset crlf
  2013.     mov    ah,prstr
  2014.     int    dos            ; print a crlf
  2015.     mov    bx,offset stscpt    ; table of items to be shown
  2016.     jmp    statc            ; finish in common code
  2017. SHSCPT    ENDP
  2018.  
  2019. SHSERV    PROC    NEAR            ; Show Server
  2020.     mov    ah,cmeol
  2021.     call    comnd            ; get a confirm
  2022.     jnc    shserv1            ; nc = success
  2023.     ret                ; failure
  2024. shserv1:mov    dx,offset crlf
  2025.     mov    ah,prstr
  2026.     int    dos            ; print a crlf
  2027.     mov    bx,offset stserv2    ; do timeout item
  2028.     call    statc
  2029.     mov    dx,offset crlf
  2030.     mov    ah,prstr
  2031.     int    dos
  2032.     mov    bx,offset stserv    ; table of items to be shown
  2033.     jmp    statc            ; finish in common code
  2034. SHSERV    ENDP
  2035.  
  2036. SHTERM    PROC    NEAR            ; Show Terminal
  2037.     mov    ah,cmeol
  2038.     call    comnd            ; get a confirm
  2039.     jnc    shterm1            ; nc = success
  2040.     ret                ; failure
  2041. shterm1:mov    dx,offset crlf
  2042.     mov    ah,prstr
  2043.     int    dos            ; print a crlf
  2044.     mov    bx,offset stterm    ; table of items to be shown
  2045.     jmp    statc            ; use common code
  2046. SHTERM    ENDP
  2047.  
  2048. ; SHOW VAR of kind \v(name)
  2049. SHOVAR    proc    near
  2050.     mov    ah,cmword
  2051.     mov    dx,offset rdbuf
  2052.     mov    bx,offset shvmsg
  2053.     mov    comand.cmper,1        ; don't react to \%x variables
  2054.     call    comnd
  2055.     jnc    shovar1            ; nc = success
  2056.     ret                ; failure
  2057. shovar1:mov    shmcnt,ax        ; save length of user spec
  2058.     mov    ah,cmeol
  2059.     call    comnd
  2060.     jnc    shovar2            ; nc = success
  2061.     ret                ; failure
  2062. shovar2:call    fshovar            ; call FAR worker
  2063.     ret
  2064. SHOVAR    endp
  2065.  
  2066. begtim    proc    near
  2067.     call    fbegtim            ; call the real FAR routine
  2068.     ret
  2069. begtim    endp
  2070. endtim    proc    near
  2071.     call    fendtim            ; call the real FAR routine
  2072.     ret
  2073. endtim    endp
  2074.  
  2075. ; SHOW STATISTICS command. Displays last operation and session statistics
  2076. shosta    proc    near            ; show file transfer statistics
  2077.     mov    ah,cmeol        ; confirm with carriage return
  2078.     call    comnd
  2079.     jnc    shosta1
  2080.     ret                ; failure
  2081. shosta1:xor    ax,ax
  2082.     call    endtim            ; update statistics, just in case
  2083.     call    fshosta            ; do a far call to worker
  2084.     ret
  2085. shosta    endp
  2086.  
  2087. ; STATUS command
  2088.  
  2089. STATUS    PROC    NEAR
  2090.     mov    ah,cmeol
  2091.     call    comnd            ; get a confirm
  2092.     jnc    stat0a            ; nc = success
  2093.     ret                ; failure
  2094. stat0a:    mov    dx,offset crlf
  2095.     mov    ah,prstr
  2096.     int    dos            ; print a crlf
  2097.                     ; STAT0 is an external ref (in mster)
  2098. STAT0:    call    cmblnk            ; clear the screen
  2099.     call    locate            ; home the cursor
  2100.     mov    bx,offset sttab        ; table to control printing
  2101.     xor    cx,cx            ; column counter
  2102.                     ; STATC is external ref in msx
  2103. STATC:    cmp    word ptr [bx],0        ; end of table?
  2104.     je    statx            ; e = yes
  2105.     cld                ; string direction is forward
  2106.     push    ds
  2107.     pop    es
  2108.     mov    di,offset rdbuf        ; point to destination buffer
  2109.     mov    byte ptr[di],spc    ; start with two spaces
  2110.     inc    di
  2111.     mov    byte ptr[di],spc
  2112.     inc    di
  2113.     push    cx            ; save column number
  2114.     push    bx
  2115.     call    [bx].sttyp        ; call appropriate routine
  2116.     pop    bx
  2117.     pop    cx
  2118.     sub    di,offset rdbuf        ; number of bytes used
  2119.     add    cx,di            ; new line col count
  2120.     push    cx            ; save col number around print
  2121.     mov    cx,di            ; how much to print now
  2122.     mov    di,offset rdbuf        ; source text
  2123.     cmp    cx,2            ; nothing besides our two spaces?
  2124.     jbe    stat5            ; e = yes, forget it
  2125.     call    prtscr            ; print counted string
  2126. stat5:    pop    cx
  2127.     add    bx,size stent        ; look at next entry
  2128.     cmp    word ptr [bx],0        ; at end of table?
  2129.     je    statx            ; e = yes
  2130.     cmp    cx,38            ; place for second display?
  2131.     jbe    stat2            ; be = only half full
  2132.     mov    dx,offset crlf        ; over half full. send cr/lf
  2133.     mov    ah,prstr
  2134.     int    dos
  2135.     xor    cx,cx            ; say line is empty now
  2136.     jmp    statc
  2137. stat2:    mov    ax,cx
  2138.     mov    cx,38            ; where we want to be next time
  2139.     sub    cx,ax            ; compute number of filler spaces
  2140.     or    cx,cx
  2141.     jle    stat4            ; nothing to do
  2142.     mov    ah,conout
  2143.     mov    dl,' '
  2144. stat3:    int    dos            ; fill with spaces
  2145.     loop    stat3            ; do cx times
  2146. stat4:    mov    cx,38            ; current column number
  2147.     jmp    statc            ; and do it
  2148. statx:    clc
  2149.     ret
  2150. STATUS    ENDP
  2151.  
  2152. ; handler routines for status
  2153. ; all are called with di/ destination buffer, bx/ stat ptr. They can change
  2154. ; any register except es:, must update di to the end of the buffer.
  2155.  
  2156.  
  2157. ; Copy dollar sign terminated string to buffer pointed at by preset di.
  2158. stmsg    proc    near
  2159.     push    ds
  2160.     pop    es        ; ensure es points to data segment
  2161.     mov    si,[bx].msg    ; get message address
  2162. stms1:    lodsb            ; get a byte
  2163.     stosb            ; drop it off
  2164.     or    al,al        ; ending on null?
  2165.     jz    stms2        ; z = yes
  2166.     cmp    al,'$'        ; end of message?
  2167.     jne    stms1        ; no, keep going
  2168. stms2:    dec    di        ; else back up ptr
  2169.     ret
  2170. stmsg    endp
  2171.  
  2172. ; get address of test value in stent. Returns address in si
  2173. stval    proc    near
  2174.     mov    si,[bx].basval    ; get base value
  2175.     or    si,si        ; any there?
  2176.     jz    stva1        ; z = no, keep going
  2177.     mov    si,[si]        ; yes, use as base address
  2178. stva1:    add    si,[bx].tstcel    ; add offset of test cell
  2179.     ret            ; and return it
  2180. stval    endp
  2181.  
  2182. ; print a single character
  2183. onechr    proc    near
  2184.     call    stmsg        ; copy message part first
  2185.     call    stval        ; pick up test value address
  2186.     mov    al,[si]        ; this is char to print
  2187.     cmp    al,7fh        ; in graphics region?
  2188.     jb    onech2        ; b = no
  2189.     mov    byte ptr [di],'\' ; do in \numerical form
  2190.     inc    di
  2191.     xor    ah,ah        ; clear high byte
  2192.     jmp    outnum        ; do number part
  2193. onech2:    cmp    al,' '        ; printable?
  2194.     jae    onech1        ; yes, keep going
  2195.     add    al,64        ; make printable
  2196.     mov    byte ptr [di],5eh    ; caret
  2197.     inc    di        ; note ctrl char
  2198. onech1:    stosb            ; drop char off
  2199.     ret
  2200. onechr    endp
  2201.  
  2202. ; numeric field
  2203. stnum    proc    near        ; for 8 bit numbers
  2204.     call    stmsg        ; copy message
  2205.     call    stval        ; pick up value address
  2206.     mov    al,[si]        ; get value
  2207.     xor    ah,ah        ; high order is 0
  2208.     jmp    outnum        ; put number into buffer
  2209. stnum    endp
  2210.  
  2211. stlnum    proc    near        ; for 16 bit numbers [jrd]
  2212.     call    stmsg        ; copy message
  2213.     call    stval        ; pick up value address
  2214.     mov    ax,[si]        ; get value
  2215.     jmp    outnum        ; put number into buffer
  2216. stlnum    endp
  2217.  
  2218. ; translate the number in ax
  2219. outnum    proc    near
  2220.     xor    dx,dx
  2221.     mov    bx,10
  2222.     div    bx        ; divide to get digit
  2223.     push    dx        ; save remainder digit
  2224.     or    ax,ax        ; test quotient
  2225.     jz    outnu1        ; zero, no more of number
  2226.     call    outnum        ; else call for rest of number
  2227. outnu1:    pop    ax        ; get digit back
  2228.     add    al,'0'        ; make printable
  2229.     stosb            ; drop it off
  2230.     ret
  2231. outnum    endp
  2232.  
  2233. ; on/off field
  2234. onoff    proc    near
  2235.     call    stmsg        ; copy message
  2236.     call    stval        ; get value cell
  2237.     mov    al,[si]
  2238.     mov    si,offset onmsg
  2239.     mov    cx,2        ; assume 2-byte 'ON' message
  2240.     or    al,al        ; test value
  2241.     jnz    onof1        ; on, have right msg
  2242.     mov    si,offset offmsg
  2243.     mov    cx,3
  2244. onof1:    cld
  2245.     push    ds
  2246.     pop    es
  2247.     rep    movsb        ; copy right message in
  2248.     ret
  2249. onoff    endp
  2250.  
  2251. ; print first message if false, second if true
  2252. msg2    proc    near
  2253.     call    stval        ; get value cell
  2254.     mov    al,[si]
  2255.     mov    si,[bx].msg    ; assume off
  2256.     or    al,al        ; is it?
  2257.     jz    msg21        ; yes, continue
  2258.     mov    si,[bx].val2    ; else use alternate message
  2259. msg21:    jmp    stms1        ; handle copy and return
  2260. msg2    endp
  2261.  
  2262. ; print first message if false, second if true, uses bit in byte for value
  2263. msg2b    proc    near
  2264.     call    stbval        ; get bit value cell
  2265.     mov    si,[bx].msg    ; assume off
  2266.     or    al,al        ; is it?
  2267.     jz    msg2b1        ; yes, continue
  2268.     mov    si,[bx].val2    ; else use alternate message
  2269. msg2b1:    jmp    stms1        ; handle copy and return
  2270. msg2b    endp
  2271.  
  2272. ; search a keyword table for a word value, print that value
  2273. srchkww    proc    near
  2274.     call    stmsg        ; copy the first message
  2275.     call    stval
  2276.     mov    ax,[si]        ; get value to hunt for
  2277.     mov    bx,[bx].val2    ; this is table address
  2278.     jmp    prttab        ; and look in table
  2279. srchkww    endp
  2280.  
  2281. ; search a keyword table for a byte value, print that value
  2282. srchkw    proc    near
  2283.     call    stmsg        ; first print message
  2284.     call    stval
  2285.     mov    al,[si]        ; get value to hunt for
  2286.     xor    ah,ah        ; high order is 0
  2287.     mov    bx,[bx].val2    ; this is table address
  2288.     jmp    prttab        ; and look in table
  2289. srchkw    endp
  2290.  
  2291. ; search a keyword table for a bit value, print that value
  2292. srchkb    proc    near
  2293.     call    stmsg            ; first print message
  2294.     call    stbval            ; get bit set or reset
  2295.     mov    bx,[bx].val2        ; this is table address
  2296.     jmp    prttab            ; and look in table
  2297. srchkb    endp
  2298.  
  2299. ; get address of test value in stent.  Returns address in si.
  2300. stbval    proc    near
  2301.     mov    si,[bx].basval        ; get address of test value
  2302.     or    si,si            ; any there?
  2303.     jz    stbva1            ; z = no, quit with no match
  2304.     mov    ax,[si]            ; get value
  2305.     test    ax,[bx].tstcel         ; bit test value against data word
  2306.     jz    stbva1            ; z = they don't match
  2307.     mov    ax,1            ;  match
  2308.     ret
  2309. stbva1:    xor    ax,ax            ; no match
  2310.     ret                ; and return it
  2311. stbval    endp
  2312.  
  2313.  
  2314. ; Print the drive name
  2315. drnum    proc    near
  2316.     call    stmsg        ; copy message part first
  2317.     call    stval        ; pick up test value address
  2318.     mov    ah,gcurdsk    ; Get current disk
  2319.     int    dos
  2320.     inc    al        ; We want 1 == A (not zero)
  2321.     mov    curdsk,al
  2322.     add    al,'@'        ; Make it printable
  2323.     cld
  2324.     push    ds
  2325.     pop    es
  2326.     stosb
  2327.     mov    word ptr [di],'\:'
  2328.     add    di,2        ; end with a colon and backslash
  2329.     mov    byte ptr [di],0    ; terminate in case drive is not ready
  2330.     xor    dl,dl        ; get current drive
  2331.     mov    ah,gcd        ; get current directory
  2332.     mov    si,di        ; current working buffer position
  2333.     int    dos
  2334.     push    cx
  2335.     push    dx
  2336.     mov    dx,di        ; directory string
  2337.     call    strlen        ; length of path part to cx
  2338.     cmp    cx,26        ; too long to show the whole thing?
  2339.     jbe    drnum3        ; be = is ok, show the whole path
  2340.     push    di        ; scan backward for last backslash
  2341.     mov    al,'\'        ; thing to search for
  2342.     std            ; backward
  2343.     mov    di,si        ; start of buffer
  2344.     add    di,cx        ; length of string
  2345.     repne    scasb        ; scan backward for a backslash
  2346.     jcxz    drnum2        ; should not happen, but then again 
  2347.     repne    scasb        ; do again for second to last path part
  2348. drnum2:    cld            ; reset direction flag
  2349.     dec    di        ; move di two places preceding backslash
  2350.     mov    [di],'--'    ; insert a missing path indicator
  2351.     dec    di
  2352.     mov    byte ptr [di],'-'
  2353.     mov    si,di        ; we will show just this part
  2354.     pop    di        ; recover main status pointer
  2355. drnum3:    pop    dx
  2356.     pop    cx
  2357.     
  2358. drnum4:    lodsb            ; copy until null terminator
  2359.     stosb
  2360.     or    al,al        ; end of string?
  2361.     jnz    drnum4        ; nz = no
  2362.     dec    di        ; offset inc of stosb
  2363.     ret
  2364. drnum    endp
  2365.  
  2366.  
  2367. ; Print the screen-dump filename [jrd]
  2368.  
  2369. pasz    proc    near
  2370.     call    stmsg        ; copy message part
  2371.     mov    si,[bx].val2    ; address of asciiz string
  2372.     push    ds
  2373.     pop    es
  2374.     cld
  2375. pasz1:    lodsb            ; get a byte
  2376.     or    al,al        ; at end yet?
  2377.     jz    pasz2        ; z = yes
  2378.     stosb            ; store in buffer
  2379.     jmp    short pasz1    ; keep storing non-null chars
  2380. pasz2:    ret
  2381. pasz    endp
  2382.  
  2383. ; Display Send and Receive chars
  2384. prsar    proc    near
  2385.     call     stmsg        ; display leadin part of message
  2386.     push    ds
  2387.     pop    es
  2388.     cld
  2389.     mov    si,[bx].tstcel    ; get address of first item
  2390.     mov    al,[si]
  2391.     cmp    al,7fh        ; DEL code?
  2392.     jne    prsar1        ; ne = no
  2393.     mov    ax,'1\'        ; say \127
  2394.     cmp    byte ptr [di-1],5eh ; caret present in msg?
  2395.     jne    prsar5        ; ne = no
  2396.     dec    di        ; remove "^"
  2397. prsar5:    stosw
  2398.     mov    ax,'72'
  2399.     stosw
  2400.     jmp    short prsar2
  2401. prsar1:    add    al,40H        ; make it printable
  2402.     stosb
  2403. prsar2:    mov    si,[bx].val2    ; get address of second msg
  2404.     call    stms1        ; add that
  2405.     mov    si,[bx].basval    ; second value's address
  2406.     mov    al,[si]        ; second value
  2407.     cmp    al,7fh        ; DEL code?
  2408.     jne    prsar3        ; ne = no
  2409.     mov    ax,'1\'        ; say \127
  2410.     cmp    byte ptr [di-1],5eh ; caret present in msg?
  2411.     jne    prsar6        ; ne = no
  2412.     dec    di        ; remove "^"
  2413. prsar6:    stosw
  2414.     mov    ax,'72'
  2415.     stosw
  2416.     ret
  2417. prsar3:    add    al,40H        ; make it printable
  2418.     stosb
  2419.     ret
  2420. prsar    endp
  2421.  
  2422. ; Display Send and Receive char value
  2423. prsarv    proc    near
  2424.     call     stmsg        ; display leadin part of message
  2425.     mov    si,[bx].tstcel    ; get address of first item
  2426.     mov    al,[si]
  2427.     xor    ah,ah
  2428.     push    bx
  2429.     call    outnum
  2430.     pop    bx
  2431.     mov    si,[bx].val2    ; get address of second msg
  2432.     call    stms1        ; add that
  2433.     mov    si,[bx].basval    ; second value's address
  2434.     mov    al,[si]        ; second value
  2435.     xor    ah,ah
  2436.     jmp    outnum
  2437. prsarv    endp
  2438.  
  2439.  
  2440. ; print Send Delay and Pause
  2441. prsnd    proc    near
  2442.     call    stmsg        ; display leadin part of msg
  2443.     mov    al,trans.sdelay    ; Send Delay (sec)
  2444.     xor    ah,ah
  2445.     call    outnum
  2446.     mov    si,offset sndmsg2 ; second part of msg
  2447.     call    stms1        ; add that
  2448.     mov    al,spause    ; Send Pause (millisec) 
  2449.     call    outnum
  2450.     mov    si,offset sndmsg3 ; last part of msg
  2451.     jmp    stms1        ; add it too
  2452. prsnd    endp
  2453.  
  2454. ; Print the handshake
  2455. prhnd:    mov    si,offset handst    ; copy in initial message
  2456.     call    stms1
  2457.     mov    si,offset nonmsg    ; assume no handshake
  2458.     mov    bx,portval
  2459.     cmp    [bx].hndflg,0        ; Is handshaking in effect?
  2460.     jne    prh0            ; Yes, print what we're using
  2461.     jmp    stms1            ; no, say so and return
  2462. prh0:    mov    al,5eh            ; Doing handshaking with control char
  2463.     push    ds
  2464.     pop    es
  2465.     cld
  2466.     stosb
  2467.     mov    al,[bx].hands
  2468.     add    al,40H            ; Make printable
  2469.     stosb                ; put in buffer
  2470.     ret
  2471.  
  2472. ; Print the Transmit Fill char
  2473. prfil:    mov    si,offset sxfilmsg    ; copy in initial message
  2474.     call    stms1
  2475.     mov    si,offset nonmsg    ; assume no handshake
  2476.     mov    al,script.xmitfill    ; filling char
  2477.     or    al,al            ; is filling in effect?
  2478.     jnz    prfil1            ; nz = yes, print what we're using
  2479.     jmp    stms1            ; no, say so and return
  2480. prfil1:    push    ds
  2481.     pop    es
  2482.     cld
  2483.     cmp    al,20h            ; printable already?
  2484.     ja    prfil2            ; a = yes
  2485.     push    ax
  2486.     mov    al,5eh            ; control char
  2487.     stosb
  2488.     pop    ax
  2489.     add    al,40H            ; make printable
  2490.     stosb                ; put in buffer
  2491.     ret                ; and return
  2492. prfil2:    cmp    al,126            ; in ordinary printable range?
  2493.     ja    prfil3            ; a = no
  2494.     stosb                ; store in buffer
  2495.     ret
  2496. prfil3:    mov    byte ptr [di],'\'    ; show as \number
  2497.     inc    di
  2498.     xor    ah,ah
  2499.     jmp    outnum            ; do rest of number
  2500.  
  2501. ; Print value from table.  BX is address of table, AL is value of variable
  2502. ; Copy value of table text entry to output buffer (di), given the address
  2503. ; of the table in bx and the value to compare against table values in al.
  2504. prttab    proc    near
  2505.     push    cx            ; save column count
  2506.     mov    cl,[bx]            ; number of entries in our table
  2507.     inc    bx            ; point to the data
  2508. prtta1:    mov    si,[bx]            ; length of keyword
  2509.     cmp    al,[bx+si+2]        ; value fields match?
  2510.     je    prtta2            ; e = yes
  2511.     add    bx,si            ; add word length
  2512.     add    bx,4            ; skip count and value fields
  2513.     dec    cl            ; more keywords to check?
  2514.     jnz    prtta1            ; nz = yes, go to it
  2515.     pop    cx
  2516.     mov    si,offset prterr
  2517.     jmp    stms1            ; copy dollar terminated string
  2518. prtta2:    push    ds
  2519.     pop    es        ; ensure es points to data segment
  2520.     mov    cx,[bx]        ; get length of counted string
  2521.     push    cx        ; save
  2522.     mov    si,bx
  2523.     add    si,2        ; look at text
  2524.     cld
  2525.     rep    movsb
  2526.     pop    ax
  2527.     pop    cx        ; original cx
  2528.     add    cx,ax        ; advance column count, return di advanced
  2529.     ret
  2530. prttab    endp
  2531.  
  2532. ; Display port speed
  2533.  
  2534. BAUDPRT    PROC     NEAR
  2535.     mov    si,offset baudrt    ; "Speed: "
  2536.     call    stms1            ; display that part
  2537.     push    di
  2538.     push    cx
  2539.     call    getbaud            ; read baud rate first
  2540.     pop    cx
  2541.     pop    di
  2542.     mov    bx,portval
  2543.     mov    ax,[bx].baud
  2544.     cmp    al,byte ptr bdtab    ; number of table entries
  2545.     jb    bdprt5            ; b = in table
  2546.     mov    si,offset unrec        ; say unrecognized value
  2547.     jmp    stms1            ; display text and return
  2548. bdprt5:    mov    bx,offset bdtab        ; show ascii rate from table
  2549.     jmp    prttab
  2550. BAUDPRT    ENDP
  2551.  
  2552. ; display Take/Macro COUNT
  2553. stcnt    proc    near
  2554.     call    stmsg            ; display leadin part of msg
  2555.     cmp    taklev,0        ; in a Take file or macro?
  2556.     jne    stcnt1            ; ne = yes
  2557.     mov    si,offset nonemsg    ; say none
  2558.     jmp    stms1
  2559. stcnt1:    push    bx
  2560.     mov    bx,takadr        ; current Take structure
  2561.     mov    ax,[bx].takctr        ; get COUNT
  2562.     pop    bx
  2563.     jmp    outnum
  2564. stcnt    endp
  2565.  
  2566. ; display Take/Macro ARGC
  2567. starg    proc    near
  2568.     call    stmsg            ; display leadin part of msg
  2569.     cmp    taklev,0        ; in a Take file or macro?
  2570.     jne    starg1            ; ne = yes
  2571.     mov    si,offset nonemsg    ; say none
  2572.     jmp    stms1
  2573. starg1:    push    bx
  2574.     mov    bx,takadr        ; current Take structure
  2575.     mov    ax,[bx].takargc        ; get ARGC
  2576.     pop    bx
  2577.     jmp    outnum
  2578. starg    endp
  2579.  
  2580. ; ALARM time
  2581. stalr    proc    near
  2582.     call    stmsg            ; display leading part of msg
  2583.     push    bx            ; preserve register
  2584.     xor    bx,bx            ; position index
  2585.     push    ds
  2586.     pop    es
  2587.     cld
  2588. stalr1:    push    bx            ; save around calls
  2589.     cmp    alrhms[bx],10        ; two digits?
  2590.     jae    stalr2            ; ae = yes
  2591.     mov    al,'0'
  2592.     stosb                ; show leading zero
  2593. stalr2:    mov    al,alrhms[bx]        ; show time component
  2594.     xor    ah,ah
  2595.     call    outnum
  2596.     pop    bx            ; recover index
  2597.     inc    bx
  2598.     cmp    bx,3            ; done all fields?
  2599.     jae    stalr3            ; ae = yes
  2600.     mov    al,':'
  2601.     stosb
  2602.     jmp    short stalr1        ; do next field
  2603. stalr3:    pop    bx
  2604.     ret
  2605. stalr    endp
  2606.  
  2607. ; show INPUT buffer
  2608. stinbuf    proc    near
  2609.     push    si
  2610.     push    di
  2611.     push    es
  2612.     mov    di,offset rdbuf
  2613.     mov    byte ptr [di],cr    ; start on the margin
  2614.     inc    di
  2615.     push    di
  2616.     call    buflog            ; get INPUT buffer pointers
  2617.     pop    di
  2618.     mov    bx,cx            ; length of buffer (and max offset)
  2619.     mov    byte ptr [di],'<'    ; start with "<# unread chars>"
  2620.     inc    di
  2621.     push    cx
  2622.     push    dx
  2623.     call    dec2di            ; ax has unread count, bufcnt
  2624.     pop    dx
  2625.     pop    cx
  2626.     mov    byte ptr [di],'>'
  2627.     inc    di
  2628. stinb1:    mov    al,es:[si]        ; extract a buffer char into al
  2629.     inc    si            ; move pointer to next byte
  2630.     test    al,80h            ; high bit set?
  2631.     jz    stinb2            ; z = no
  2632.     mov    byte ptr [di],'~'    ; yes, show a tilde
  2633.     inc    di
  2634. stinb2:    and    al,7fh            ; strip eighth bit
  2635.     cmp    al,' '            ; control code?
  2636.     jae    stinb3            ; ae = no
  2637.     mov    byte ptr [di],'^'    ; yes, show caret
  2638.     inc    di
  2639.     or    al,40h            ; convert char to upper case letter
  2640. stinb3:    mov    [di],al
  2641.     inc    di            ; where to write next byte
  2642.     cmp    di,offset rdbuf+78    ; line full?
  2643.     jb    stinb4            ; b = no, have more room
  2644.     mov    word ptr [di],0a0dh    ; add cr/lf
  2645.     mov    byte ptr [di+2],0
  2646.     mov    dx,offset rdbuf
  2647.     mov    di,dx
  2648.     call    prtasz
  2649. stinb4:    cmp    si,bx            ; beyond end of Input buffer?
  2650.     jb    stinb5            ; b = not yet
  2651.     xor    si,si            ; reset to start of INPUT-buf (wrap)
  2652. stinb5:    loop    stinb1
  2653.     mov    word ptr [di],0a0dh    ; add cr/lf
  2654.     mov    byte ptr [di+2],0
  2655.     mov    dx,offset rdbuf        ; reset to start of our local buffer
  2656.     mov    di,dx
  2657.     call    prtasz
  2658.     pop    es
  2659.     pop    di
  2660.     pop    si
  2661.     xor    cx,cx
  2662.     ret
  2663. stinbuf    endp
  2664.  
  2665. ; LNOUT - Table driven unsigned long integer (32 bit) display
  2666. ; Register dx holds high order word and ax holds low order word of unsigned
  2667. ; long integer to be stored in decimal. Storage area is given by DS:[DI]
  2668. ; DI is incremented for each storage, null terminated.
  2669. ; Table TENS holds set of double word values of ten raised to powers 0 to 9
  2670. ; TENSLEN holds the number of these double words
  2671. ; All registers preserved.    8 March 1987 [jrd]
  2672.  
  2673. lnouts    proc    near            ; do lnout with thousands separator
  2674.     push    ax
  2675.     mov    al,thsep        ; get thousands separator
  2676.     mov    lnoutsep,al        ; tell lnout to use it
  2677.     pop    ax
  2678.     call    lnout            ; compute value to di
  2679.     mov    lnoutsep,0        ; clear for future callers
  2680.     ret
  2681. lnouts    endp
  2682.  
  2683. lnout    proc    near
  2684.     push    ax
  2685.     push    bx
  2686.     push    cx
  2687.     push    dx
  2688.     push    si
  2689.     xor    si,si        ; flag to say start printing (no leading 0's)
  2690.     mov    cx,tenslen    ; number of table entries
  2691. lnout1:    push    cx        ; save loop counter
  2692.     mov    bx,cx        ; index into tens double word table
  2693.     dec    bx        ; index starts at zero
  2694.     add    bx,bx
  2695.     add    bx,bx        ; bx times four (double words to bytes)
  2696.     xor    cx,cx        ; cx is now a counter of subtractions
  2697.  
  2698. lnout2:    cmp    dx,word ptr tens[bx+2]  ; pattern 10**(bx/4), high order part
  2699.     jb    lnout4        ; b = present number is less than pattern
  2700.     ja    lnout3        ; a = present number is larger than pattern
  2701.     cmp    ax,word ptr tens[bx] ; high words match, how about lows
  2702.     jb    lnout4        ; b = present number is smaller than pattern
  2703. lnout3:    sub    ax,word ptr tens[bx]    ; subtract low order words
  2704.     sbb    dx,word ptr tens[bx+2]    ; subtract high order words, w/borrow
  2705.     inc    cl        ; count number of subtractions
  2706.     inc    si        ; flag to indicate printing needed
  2707.     jmp    short lnout2    ; try again to deduct present test pattern
  2708.  
  2709. lnout4:    or    bx,bx        ; doing least significant digit?
  2710.     jz    lnout5        ; z = yes, always print this one
  2711.     or    si,si        ; should we print?
  2712.     jz    lnout6        ; z = no, not yet
  2713. lnout5:    add    cl,'0'        ; get number of subtractions
  2714.     mov    [di],cx        ; store it (ch is still zero), asciiz
  2715.     inc    di
  2716.     cmp    bx,9*4        ; places for thousands separator?
  2717.     je    lnout5a        ; e = yes
  2718.     cmp    bx,6*4
  2719.     je    lnout5a
  2720.     cmp    bx,3*4
  2721.     jne    lnout6        ; ne = no
  2722. lnout5a:mov    cl,lnoutsep    ; get thousands separator
  2723.     jcxz    lnout6        ; z = none
  2724.      mov    word ptr [di],cx
  2725.     inc    di
  2726. lnout6:    pop    cx        ; recover loop counter
  2727.     loop    lnout1
  2728.     pop    si
  2729.     pop    dx
  2730.     pop    cx
  2731.     pop    bx
  2732.     pop    ax
  2733.     ret
  2734. lnout    endp 
  2735.  
  2736. code    ends
  2737.     end
  2738.